1

When the following program is run, then line 10 is skipped, and the buffer n[100] contains '\n' only. So, the user is not allowed to save any data in n. Could you please point what's wrong with the codes? This issue does not happen when line 8 is deleted.

#include <stdio.h>

int main(void)
{
    char n[100] = "";
    char m[100] = "";
    char c = '0';
    c = fgetc(stdin);
    printf("First :");
    fgets(n, 30, stdin);
    printf("\nSecond :");
    fgets(m, 30, stdin);
    return 0;
}

My input to fgetc was 2\n.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Nownuri
  • 689
  • 2
  • 7
  • 19
  • 3
    What was your input, and what did you expect? Assuming you entered something like `x\nfirst\nsecond\n` line 10 was not skipped. It executed and read everything to the end of the current input line, which happened to be just the ending newline left behind after the previous `fgetc` call. – dxiv Nov 29 '20 at 07:16
  • 1
    *"line 10 is skipped, and the buffer n[100] contains '\n'"* - that alone should tell you the line isn't skipped; it executed and a newline was all you got for the effort. Because.. that's what `fgets` *does*. It reads until the length is exhausted (less one to leave space for the terminator), or it encounters a newline (which it retains, then terminates the string), whichever comes first. Given that, what were you expecting? – WhozCraig Nov 29 '20 at 07:18
  • @dxiv I edited the question. The input was '2' and 'enter'. – Nownuri Nov 29 '20 at 07:19
  • 1
    @Nownuri See my first comment. `fgetc` read character `'2'` then `fgets` read string `"\n"`. – dxiv Nov 29 '20 at 07:20
  • @dxiv It's strange. The input "\n" happend before calling the printf function.. Anyway, then how could I input only one character to fgetc? – Nownuri Nov 29 '20 at 07:23
  • @Nownuri `stdin` is the input stream, and what you entered stays in it until it's read, regardless of any intervening `printf`. I suggest you re-read the documentation for [fgetc](https://en.cppreference.com/w/c/io/fgetc) and [fgets](https://en.cppreference.com/w/c/io/fgets). Also see [How to avoid pressing Enter with getchar() for reading a single character only?](https://stackoverflow.com/questions/1798511/how-to-avoid-pressing-enter-with-getchar-for-reading-a-single-character-only) about `stdin` buffering. – dxiv Nov 29 '20 at 07:26
  • @dxiv Of course I have read a C textbook. The problem is not all books expalin the low level process. Could you tell me how one can use fgetc and fgets in a row without making \n stored in the buffer as above? What's the appropriate input for fgetc? – Nownuri Nov 29 '20 at 07:30
  • @Nownuri clear the buffer by reading the newline after `fgetc`. Also, consider reading cppreference whenever you want to use a library function - it should be pretty ideal for understanding what each function actually does. Just in case whichever book you're following doesn't explain what you want – Chase Nov 29 '20 at 07:30
  • @Nownuri You can't read a single character in C without pressing Enter, at least not in a portable way. That's elaborated in more detail under the question at the previous link. In the posted code, if you enter `2first\nsecond\n` the variables will get set to `c = '2'`, `n = "first\n"`, `m = "second\n"`. – dxiv Nov 29 '20 at 07:32
  • @Chase Thank you for the solution. But is there a more natural way than to use fgetc again? Using fgetc again for this purpose seems like a workaround that can confuse myself later unless I comment on the code specifically. – Nownuri Nov 29 '20 at 07:34
  • @Nownuri use `fgets` on both instances, your goal is to read 2 lines for 2 values. That translates to 2 `fgets`, you can do the parsing yourself afterwards – Chase Nov 29 '20 at 07:37
  • @Chase Okay, this implies fgets is always preferred than fgetc in a similar way as how fgets is preferred over scanf... I suppose there's no ASNI C function which is made only for clearing the stdin buffer? – Nownuri Nov 29 '20 at 07:41
  • 1
    @Nownuri No, the only way to clear the stdin buffer is to read from it. As a side note, [never use `fflush` to clear `stdin` or any other input streams](https://stackoverflow.com/questions/2979209/using-fflushstdin), in case you stumble upon such advice from questionable sources. – Chase Nov 29 '20 at 08:04

0 Answers0