DrDavid
DrDavid

Reputation: 964

Using a getchar() while loop; but, results are kinda strange

I'm working my way through "The C Programming Language" (K&R), and did one of the exercises. The exercise was to print the number of spaces, tabs and newlines until EOF. Great, that works. But, I started getting clever and added the printf()'s you see below that actually say, "Space" or "Tab" or "newline". It should print that as I type, but, it the while loop only seems to run once I hit enter.

The code:

#include <stdio.h>

int main(int argc, const char * argv[])
{

    int c, nb, nt, nl;

    nb = nt = nl = 0;

    while ((c = getchar()) != EOF) {
        if (c == ' ') {
            nb += 1;
            printf("Space\n");
        }
        if (c == '\t') {
            nt += 1;
            printf("Tab\n");
        }
        if (c == '\n') {
            nl += 1;
            printf("New Line\n");
        }

    }

    printf("%d spaces, %d tabs, %d newlines",nb,nt,nl);

    return 0;
}

The output:

a b
Space
New Line
c d e
Space
Space
New Line
f   g
Tab
New Line
3 spaces, 1 tabs, 3 newlines

What I expected to see was something more like this:

a Spaceb
New Line
c Spaced Spacee
New Line
f   tabg
New Line
3 spaces, 1 tabs, 3 newlines

So, why do I get what I get, and not what I expect?

And, yes, if I was really caring, I'd make the words 'space[s]' 'tab[s]' and 'newline[s]' plural vs. not based on the value, but, it's just an exercise. ;)

Upvotes: 2

Views: 195

Answers (1)

chill
chill

Reputation: 16888

Your terminal is in canonical mode - characters are accumulated until end of line. Only then are they send to user (one by one).

If you want immediate response, you have to switch the terminal to raw mode.

PS. More or less, like this:

struct termios t;

tcgetattr (0, &t);

t.c_lflag &= ~ICANON;
t.c_cc [VMIN] = 1;
t.c_cc [VTIME] = 0;

tcsetattr (0, TCSANOW, &t);

Upvotes: 1

Related Questions