user6723034 user6723034 - 3 months ago 16
C Question

C programming, Can anyone explain this?

#include <stdio.h>

int main() {
int c;

while ((c = getchar()) != EOF) {
if (c == '\t')
printf("\\t");
else if (c == '\b')
printf("\\b");
else if (c == '\\')
printf("\\\\");
else
putchar(c);
}
return 0;
}


In this case for an input of

hi how are you\doing


I get an output

hi\thow\tare\tyou\\doing


#include <stdio.h>

int main() {
int c;

while ((c = getchar()) != EOF) {
if (c == '\t') {
c = '\b';
printf("\\t");
}
if (c == '\b') {
c = '\b';
printf("\\b");
}
if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
}
return 0;
}


When I run this program with an input

hi how are you\doing


(The large spaces being tabs)

I get this output

hi\t\how\t\are\t\you\doing


Code:

#include <stdio.h>

int main() {
int c;
c = '\b';
putchar(c);
return 0;
}


On running this,
I get nothing. No output. Back to the shell prompt.

To be more precise, in the first program I get the output I want, but in the second program I get the backslashes after every
\t
but not after the
\
I would expect
\\\
to be the output looking at how
\t
became
\t\
, is '\b' causing it? if it is, how does it work? but if so why doesn't the same happen in the third program?

Ran this on rasbian default gcc compiler and mingw msys-gcc package for windows.

Answer

The reason the second program is behaving that way is because you are entering more than one if block:

    if (c == '\t') {
        c = '\b';
        printf("\\t");
    }
    if (c == '\b') {
        c = '\b';
        printf("\\b");
    }
    if (c == '\\') {
        c = '\b';
        printf("\\\\");
    }
    putchar(c);

When you encounter a tab, the first block is entered where it prints \t to the screen then changes c to a backspace.

The second block is then entered because c is a backspace (because you just changed it to be that). That block then prints \b to the screen, so now you have \t\b on the screen.

When you then call putchar to write the backspace, the b will get overwritten by the next character. So when the next character is written you then have \t\ on the screen.

So the problem here is that you're testing c multiple times and potentially changing it in between. The reason this happens only with the tab is because you check for the tab first, then the backspace, then the backslash.

If you use else if instead of if, you won't enter multiple blocks:

if (c == '\t') {
    c = '\b';
    printf("\\t");
}
else if (c == '\b') {
    c = '\b';
    printf("\\b");
}
else if (c == '\\') {
    c = '\b';
    printf("\\\\");
}
putchar(c);

With this change, given the original input, the output will be:

hi\how\are\you\doing