我写了一个简单的代码来从键盘上读取一个字符,但程序失败了,为什么?我如何阅读char?只有在阅读一个换行符后有什么更好的方法来读取字符?
int main(int argc, char** argv)
{
char op;
do
{
printf("¿Sigues?");
scanf("%c",&op);
}while(op=='s' || op=='S');
return 0;
}
我写了一个简单的代码来从键盘上读取一个字符,但程序失败了,为什么?我如何阅读char?只有在阅读一个换行符后有什么更好的方法来读取字符?
int main(int argc, char** argv)
{
char op;
do
{
printf("¿Sigues?");
scanf("%c",&op);
}while(op=='s' || op=='S');
return 0;
}
您的问题是%c
转换说明符不会导致scanf()
跳过前导空格。读取输入后,您需要处理仍在流中的换行符。
当scanf()
被第一次通过循环调用时,输入流为空,因此它会等待您键入内容。您输入s
并按Enter键,因此输入流包含字符s
和\n
(换行符)。 scanf()
从输入流中移除s
并将其分配给op
。当第二次调用scanf()
时,输入流为而不是为空;它仍然有\n
字符,所以scanf()
会读取它并将其分配给op
,这会导致循环条件失败,因此您的循环将退出。
有几种方法可以解决此问题。我要推荐阅读串而不是使用fgets()
单个字符,如下所示:
char op[3] = {0}; // input character + newline character + 0 terminator
do
{
printf("¿Sigues?");
if (fgets(op, sizeof op, stdin))
{
/**
* Check for a newline character in the input. If it's not there
* then the user typed in too many characters. In order to keep
* the input stream from getting clogged up with bad input, read
* until we find a newline character.
*/
char tmp[3];
char *newline = strchr(op, '\n');
while (!newline && fgets(tmp, sizeof tmp, stdin))
{
newline = strchr(tmp, '\n');
}
}
else
{
printf("Error while reading input\n");
op[0] = 0;
}
} while (tolower(op[0]) == 's');
就是这样,非常感谢你的解释。 – 2010-10-21 20:14:17
op = getc(stdin);
非常感谢, 你能解释一下他们之间的区别吗? – 2010-10-21 19:29:18
原始文章中的循环将产生与'scanf(“%c”)'相同的结果。 'getc(stdin)'仍然只能读取一个字符,而标准输入中仍然会有'\ n'。 – BeeBand 2010-10-21 20:31:47
scanf函数刷新。它不能以平台独立的方式完成
你看到一行“Sigues”两次,因为在输入流中有一个\n
依然。如果你输入一个字符并按回车,你的输入流中现在有两个字符。您的scanf
格式化程序只指定一个字符,因此scanf
会读入一个字符,然后前进。但是,流中的下一个字符是\n
,因此在第二个循环中退出循环。
注意: @ eduffy的技巧getc(stdin)
会做同样的事情,stdin中仍然有\n
。你需要以某种方式超过\n
。
如何读你的字符,然后chomping其余的流到\n
字符?我试过这个,它适用于我:
char op;
do
{
printf("¿Sigues?");
scanf("%c",&op);
while(getchar() != '\n') continue;
}while(op=='s'|| op=='S');
“程序失败”,你能解释程序如何失败吗? – JoshD 2010-10-21 19:24:30
它总是只写2次“Sigues”。 – 2010-10-21 19:31:19