fgetc(stdin) in a loop is producing strange behaviour

最后都变了- 提交于 2019-12-17 22:02:21

问题


I have this code

while(1){
    printf("hello world !\n");
    fgetc(stdin);
}

when this runs and I enter a letter like this:

hello world !
a

it ignores the fgetc(stdin) in the next loop and prints hello world twice without waiting for input.

hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !

I have tried putting fflush(stdin) before or after the fgetc(stdin) but it still produces the same behaviour, what am I doing wrong ?


回答1:


Terminals tend to be line-buffered, meaning that stream contents are accessible on a line-by-line basis.

So, when fgetc starts reading from STDIN, it's reading a full line, which includes the newline character that ended that line. That's the second character you're reading.

As for fflush, that's for flushing output buffers, not input buffers.

So, what you want to do here is to purge the input buffer by reading from it until its empty, or just explicitly ignore newline characters.




回答2:


That's because you actually enter two characters: 'a' and a newline. Also, since terminal is normally line-buffered your program will only see your input once you hit the newline. It'll be informative to enter a longer line of text, too.

If you want to change this behavior you have two options: reading entire lines (i.e. all characters up to a newline or end-of-file) or switching terminal to non-canonical mode. The latter makes sense if you're working on an interactive terminal application like a text editor. See termios manpage for details. In short, you'll want to set MIN and TIME options to zero to make reads from terminal return immediately as data becomes available. If you do go down this path, make sure you switch the terminal back when you exit, including due to reception of a signal.

fflush() affects the output, not the input.




回答3:


There are two characters: a and \n (newline). Your loop reads reads the a, then loops and prints "hello world !". It then sees \n and loops and prints "hello world !". When you type a+\n in the terminal, it's storing the two characters in the stdin buffer. fgetc(stdin); will read from the stdin buffer if there is a char available, otherwise it waits until a char is added to the buffer.

Since terminals are line-buffered (ie, do not send the content to the program until a newline is reached) you have a few options:

  • read the entire line into a buffer, but take only the first character
  • ignore newlines
  • turn off line-buffering

To turn off line buffering, look at http://c-faq.com/osdep/cbreak.html and http://www.flipcode.com/archives/_kbhit_for_Linux.shtml and http://ubuntuforums.org/showthread.php?t=225713 (although I have not tested any of the code here).




回答4:


You have two characters there, 'a' and '\n'. That is the problem, because fgetc will only read ONE character. This is the documentation.

If you enter only a '\n' - hit enter only - you will have the expected behaviour.

Hope it helps!



来源:https://stackoverflow.com/questions/12063879/fgetcstdin-in-a-loop-is-producing-strange-behaviour

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!