0

I was experimenting with C's fgetc() and ran into a strange problem. I typed the following code below:

    int answer = 0;

    printf("Input1\n");

    answer = fgetc(stdin);
    printf("%c\n", answer);

    printf("Input2\n");
    answer = fgetc(stdin);
    printf("%c\n", answer);

However, every time I enter a value other than a space, this happens:

 Input1
 1
 1
 Input2 # It doesn't wait for my input here

Could anyone tell me what I'm doing wrong? I've tried flushing stdin and I've also tried using rewind on stdin. However, none of these work.

ssharma
  • 153
  • 2
  • 13
  • 1
    After the first character, there is a newline waiting to be read, so `fgetc()` doesn't need to wait for more input. Consider reading lines with standard C [`fgets()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html) or POSIX [`getline()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html) and then parse the input. – Jonathan Leffler Jan 08 '18 at 00:46
  • Classic mistake. – lost_in_the_source Jan 08 '18 at 01:03

1 Answers1

1

If you type in 1 followed by enter, there is \n char at the end of input. The second fgetc will read the \n character.

For debugging (as suggested in comments) you can replace printf("%c\n", answer) with

printf("Got %d (%c)\n", answer, (isprint(answer) ? answer : '.'));

The result should be:

Input1
1
Got 49 (1)
Input2
Got 10 (.) <- new line
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • 1
    `%c` is OK as a format specifier; using `%d` may be better for debugging, but `%c` isn't automatically wrong (indeed, it is often, even usually, right!). – Jonathan Leffler Jan 08 '18 at 00:47
  • @JonathanLeffler The asker declared `int answer = 0;` – Barmak Shemirani Jan 08 '18 at 00:49
  • And? That's the correct type to receive the value from `fgetc()` because it returns an `int`. It has to return an `int` because it returns every possible `char` value (converted to `unsigned char` and then `int`) plus one exceptional value, EOF, which is negative (usually but not necessarily `-1`). So a `char` can't hold that many different values, and `fgetc()` therefore returns an `int`. Yes, the code should check that it didn't get `EOF` before printing with `%c`, but using `%c` to print an `int` containing a character is fine, and normal. – Jonathan Leffler Jan 08 '18 at 00:53
  • Indeed, if you take a `char` variable and pass it to `printf()`, it will be converted to `int` automatically, because all the arguments in the ellipsis section of a variadic function like `printf()` undergo default argument conversions — `char` and `short` values are converted to `int` and `float` values are converted to `double`. It's why there was no need for separate format specifiers for `float` and `double`; the values passed to `printf()` were always `double`. – Jonathan Leffler Jan 08 '18 at 00:57
  • Oh, sorry, I got confused. I see your point about the usefulness in debugging. – Barmak Shemirani Jan 08 '18 at 00:59
  • 2
    For debugging, printing it in both formats is good: `printf("Got %d (%c)\n", answer, (isprint(answer) ? answer : '.'));` works quite well, printing a dot when the character isn't printable. Or you can avoid printing the character notation when it isn't printable. Or … – Jonathan Leffler Jan 08 '18 at 01:02