使用 %c 输入错误
考虑以下代码片段:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("%c", &y);
printf("%d %c", x, y);
}
行为:
当您运行上述程序时,第一个 scanf 被调用,它将等待您输入一个十进制数。假设您输入 12(即 ASCII '1' 和 ASCII '2')。然后按“enter”键表示输入结束。接下来程序将执行第二个scanf,但您会注意到程序不会等待您输入字符,而是直接输出12,后跟'\n'。
解释:
为什么会这样?让我们逐步看一下程序的行为。最初缓冲区中没有任何内容。当第一个 scanf() 被调用时,它没有要读取的内容,所以它等待。它一直等到您输入 1,2,然后“输入”。现在缓冲区中的内容是字符 1、字符 2 和字符 '\n'。请记住,'\n' 表示输入结束,一旦输入了所有字段,但它也作为 ASCII 字符存储在缓冲区中。此时 scanf 将从缓冲区中读取最大的十进制输入并将其转换为整数。在此示例中,它找到字符串“12”并将其转换为十进制值 12 并将其放入 x 中。然后scanf将控制权返回给主函数并返回值1,能够成功转换一个条目。在我们的示例中,我们没有在变量中捕获 scanf 的返回值。对于健壮的代码,检查 scanf() 的返回值以确保用户输入正确的数据很重要。
现在留在缓冲区中的是'\n'。接下来,调用第二个 scanf 并期待一个字符。由于缓冲区中已经有 '\n' 字符,scanf 看到它,从缓冲区中取出它,并将其放入 y 中。这就是为什么当你之后执行 printf 时,12 和“enter”会打印到屏幕上。
解决方案:
故事的寓意是,enter 是一个和其他字符一样的字符,并且被输入到缓冲区,并像任何其他 ASCII 字符一样被 %c 从缓冲区消耗。要解决此问题,请尝试改用此代码:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("\n%c", &y); /* note the \n !! */
printf("%d %c", x, y);
}
**
这如何解决问题?
** 所以你再次输入 '1','2','\n'。第一个 scanf 读取“1”和“2”,将其转换为十进制十二并将 '\n' 留在缓冲区中。下一个 scanf 现在期望在下一个输入的开头有一个 '\n'。它在缓冲区中找到'\n',读取它,然后丢弃它。现在缓冲区是空的,scanf 正在等待用户输入一个字符。假设用户输入“c”,然后输入回车键。'c' 现在分配给 y,而不是“输入”。因此 printf 将在屏幕上输出“12 c”。注意:现在队列中还有一个“\n”。因此,如果您需要对单个字符执行另一个 scanf,则必须先“使用”该 '\n',然后再从用户那里获取另一个字符。
这对于任何其他格式说明符都不是问题,因为它们都忽略输入前的空格。