简体   繁体   English

在stdin中非法使用fflush()吗? 该怎么做呢?

[英]Illegal to use fflush() in stdin? What to do instead?

char c;
char s[32];
puts("Type a char");
c=getchar();
fflush(stdin);
puts("Type a string");
fgets(s,32,stdin);

Without the fflush(), if you type a character, say "a", and the hit enter, the input buffer contains "a\\n", the getchar() peeks the "a", but the "\\n" remains in the buffer, so the next fgets() will find it and return an empty string without even waiting for user input. 如果没有fflush(),则键入一个字符,说“ a”,然后按回车键,输入缓冲区将包含“ a \\ n”,getchar()会窥视“ a”,但“ \\ n”仍保留在缓冲区,因此下一个fgets()将找到它并返回一个空字符串,而无需等待用户输入。

What should be done instead? 应该怎么做呢? As far as i know, it's not defined or standard to use fflush() on an input stream? 据我所知,在输入流上使用fflush()是没有定义的还是标准的?

Don't use getchar when your intent is to read a line of input and interpret one character from it. 如果您打算读取一行输入并解释其中的一个字符,请不要使用getchar In this case, read a line with fgets or similar and just inspect the first line. 在这种情况下,读取包含fgets或类似内容的行,然后检查第一行。

Alternatively, you can stick with getchar , but then you need to keep reading characters until the end of the line and throw them away before moving on. 另外,您可以坚持使用getchar ,但是随后您需要继续读取字符,直到行尾为止,然后将它们扔掉再继续。

Your program could be transformed to (first approach): 您的程序可以转换为(第一种方法):

char c;
char s[32];
puts("Type a char");
fgets(s,32,stdin);
c=s[0];
puts("Type a string");
fgets(s,32,stdin);

Note that this is missing checking of return values and doesn't handle input longer than 32 bytes, but it's a start and those are separate issues you can work on. 请注意,这缺少对返回值的检查,并且不能处理超过32个字节的输入,但这只是一个开始,您可以单独处理这些问题。

If you are trying to discard the rest of the input line, then do this: 如果您要舍弃其余的输入行,请执行以下操作:

int ch;
while ( (ch = getchar()) != '\n' && ch != EOF) { }

This reads characters until there are no more, or it hits the end of the line. 这将读取字符,直到没有更多字符为止,否则它将到达行尾。

Note that you should be using int c; 注意,您应该使用int c; rather than char c; 而不是char c; . The getchar() function actually does not return a char value; getchar()函数实际上不返回char值; it returns the result of converting that char to unsigned char . 它返回将该char转换为unsigned char

Read about fflush(3) ; 了解有关fflush(3)的信息 you probably want to call fflush(NULL); 您可能要调用fflush(NULL); before c=getchar(); c=getchar(); but that might not work as you want. 但这可能无法如您所愿。

Remember that on Linux at least the terminal is often kernel buffered (and also stdio buffered). 请记住,至少在Linux上,终端通常是内核缓冲的(还有stdio缓冲的)。 Read more about tty -s. 了解有关tty -s的更多信息。 So you often won't get any input till the user pressed the enter key. 因此,在用户按下Enter键之前,您通常不会得到任何输入。

You should rethink your program and read entire lines (often with getline(3) or fgets(3) on a large enough buffer). 您应该重新考虑程序并读取整行(通常在足够大的缓冲区上使用getline(3)fgets(3) )。

If you want to get individual key presses on Linux (or other POSIX systems) you need a library like ncurses (which works with the terminal in raw mode). 如果要在Linux(或其他POSIX系统)上获得单个按键,则需要ncurses之类的库(可在原始模式下与终端一起使用)。 You might be interested in readline(3) 您可能对readline(3)感兴趣

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM