james
james

Reputation: 103

C code, scanf and getchar

I'm just asking what does the getchar do in this code and how does it work? I don't understand why the getchar affects the code, to me it seems as if its just getting the value but nothing is being done with the value.

int c=0;
while (c>=0)
{
  scanf("%d", &c);
  getchar();
}

Upvotes: 4

Views: 332

Answers (4)

P.P
P.P

Reputation: 121387

Some possibilities of why getchar() might have been used there:

1) If it's done to ignore whitespaces (typically used when scanning chars with %c), it's not needed here because %d ignores whitespaces anyway.

2) Other possibility is that after this loop, some further scanning is done where the last \n left by the last call to scanf() might be a problem. So, getchar() might be used to ignore it.

3) In case you enter characters do not match %d, scanf() will fail. In that the characters you entered are left in the input stream and you'll never be able to read an int again (For example, if you input abcdddgdfg without that getchar() call). So, getchar() here will consume all those chars (one per iteration) and eventually you'll be able to read int (using %d) again.

But this is all really not needed; it's just an attempt to fix flaws of scanf(). Reading inputs using scanf() and getting it correct is really difficult. That's why it's always recommended to use fgets() and parse using sscanf() or using strto*() functions if you are just scanning integers.

See: Why does everyone say not to use scanf? What should I use instead?

Upvotes: 3

chux
chux

Reputation: 153457

getchar(); is simply reading and consuming the character after the number, be it a space, comma, new line or the beginning of another integer or anything else.

IMO, this is not robust code. Good code would 1) at least test the result of scanf() and 2) test or limit the consumption of the following character to prevent "eating" a potential sign of the following number. Remember code cannot control what a user types, but has to cope with whatever is entered.

    v space
"123 456"

    v comma
"123,456"

    v negative sign
"123-456"

Upvotes: 0

zwol
zwol

Reputation: 140569

In this code, getchar is being called for its side effects: it reads a character from standard input and throws it away.

Probably this is reading input from the user. scanf will consume a number, but leave the newline character after the number untouched. The getchar consumes the newline and throws it away. This isn't strictly necessary in this loop, because the next scanf will skip over whitespace to find the next number, but it might be useful if the code after the loop isn't expecting to have a newline as the first thing on stdin.

This code is buggy, because it doesn't check for EOF, because it doesn't do anything sensible when the input is not a number or when there's more text on the line after the number, and because it uses scanf, which is broken-as-specified (for instance, it's allowed to crash the program if the input overflows the range of an int). Better code would be something like

char *linep = 0;
size_t asize = 0;
char *endp;
long c;
while (getline(&linep, &asize, stdin) > 0) {
    errno = 0;
    c = strtol(linep, &endp, 10);
    if (linep == endp || *endp != '\0' || errno) {
        puts("?Redo from start");
        continue;
    }
    if (c == 0) break;
    do_something_with(c);
}
free(linep);

Upvotes: 1

lostbard
lostbard

Reputation: 5220

Most likely the code is for reading in a list of integers, separated by a new line.

scanf will read in an integer, and put it into variable c.

The getchar is reading in the next character (assuming a new line)

Since it doesn't check, there is some potential that it wasn't a new line, or that scanf failed as the what it tried to read wasn't a number.

Upvotes: 0

Related Questions