1
#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.

  • 2
    `'\b'` is "backspace". So you get nothing. – Weather Vane Aug 16 '16 at 17:37
  • Yes, but in case of the first output, I get a "\" after "\t" and when it's supposed to print "\\" it just prints "\" – user6723034 Aug 16 '16 at 17:40
  • 3
    `'\\'` is an *escape*. Normally the single `'\'` is part of an *escape sequence* such as `'\b'`. Putting a double slash defeats the escape, giving a single slash as actual output. Similarly with `"%"` in `printf` which normally signifies a format spec. If you really want a percent sign, you have to put `"%%"` to defeat the expected sequence. – Weather Vane Aug 16 '16 at 17:45
  • But I gave `printf("\\\\");` so wouldn't I get two single slash as output? Also edited the question to make it more precise. – user6723034 Aug 16 '16 at 17:48
  • 1
    You followed it with a backspace using `putchar(c);`. – Weather Vane Aug 16 '16 at 17:49
  • In that case I should be getting `hi\how\are\you\doing`, no? If the backspace is erasing a single slash at the end of the output, why doesn't it do the same with `t` from `\t` in the first three instances, instead it puts out `\t\`, so I'm confused. – user6723034 Aug 16 '16 at 17:52
  • 1
    Sorry, which program is at fault? The question itself is confusing. I suggest you experiment with simple program. – Weather Vane Aug 16 '16 at 17:58
  • The second program is at fault, rather giving out unexpected output. This is one of the starting exercises of "The C Programming Language by Dennis Ritchie and Brian Kernighan" Thanks for the time tho! – user6723034 Aug 16 '16 at 18:00

1 Answers1

2

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
dbush
  • 205,898
  • 23
  • 218
  • 273