int main (int argc, char *argv [])
{
char a = 'v';
for (int i = 0; a != 'x'; )
{
printf("Enter 'a' : ");
scanf("%c",&a);
}
return 0;
}
我运行它并输入了 k 。当我在此之后按下Enter时,为什么我的printf
在循环第二次运行时 2次?
答案 0 :(得分:3)
要了解这种行为,我们可以逐步模拟执行过程。
printf("Enter 'a' : ");
scanf("%c",&a); // User type in example 'a' and presses enter.
scanf
“缓冲” a\n
,并将值a
放在'a'
中
不满足循环条件,因为'a' == 'x'
为false
printf("Enter 'a' : ");
scanf("%c",&a); // The buffer still contains `'\n'`
由于缓冲区仍然包含未消耗的数据,因此下一个字符('\n'
)被放置在a
中,并且循环继续进行。
不满足循环条件,因为'\n' == 'x'
为false
printf("Enter 'a' : ");
scanf("%c",&a); // The buffer is empty now.
这给您一种错觉,就是循环显示两倍的printf
,但是实际上,scanf
不需要用户输入就可以继续读取缓冲区。
如果您输入更多字符,在示例qwerty
中,"Enter 'a' : "
将显示7次,因为"qwerty"
包含6个字符+ '\n'
请注意,使用while (a != 'x')
比for (int i = 0; a != 'x'; )
更适合您的需求
答案 1 :(得分:2)
使用scanf
和%c
时,它将读取任何字符-包括按ENTER键时获得的换行符。
因此,如果您运行该程序并键入
a <Return>
您需要进行两次旅行:一次阅读'a'
,另一次阅读'\n'
。如果您输入
<Space> <Space> a <Return>
它通过循环跳了四下。如果您输入
x <Return>
它只会循环一次,因为它会通知您键入了'x'
并退出。
如果您打印出收到的每个字符,事情将变得更加清晰
for (int i = 0; a != 'x'; )
{
printf("Enter 'a' : ");
scanf("%c",&a);
printf("you typed %d = %c\n", a, a);
}
看到它打印时
you typed 10 =
这是换行符之一。 ('\n'
的值为ASCII 10。)
我说过%c
读任何字符-但这有点不寻常。 scanf
的其他大多数格式说明符-%d
,%f
,%s
等-跳过“空白”,即空格,制表符,换行符,以及其他一些。但是%c
不会跳过那些字符,因为它的工作是只读取一个字符,并且有人认为您可能也希望使用它来读取空白字符。
答案 2 :(得分:2)
对于初学者而言,此循环
for (int i = 0; a != 'x'; )
至少没有意义,因为循环中未使用变量i
。
也是此提示
printf("Enter 'a' : ");
仅会使用户感到困惑。您正在要求用户输入字符'a'
,而在输入字符'x'
时循环停止。
这是scanf的呼叫
scanf("%c",&a);
读取所有字符,包括空格字符。这就是循环再次迭代的原因。你必须写
scanf( " %c", &c );
^^^
在这种情况下,空白将被跳过。
根据C标准(7.21.6.2 fscanf函数)
5由空格字符组成的指令由以下命令执行 读取输入内容,直到第一个非空白字符(仍保留 未读),或者直到无法再读取任何字符为止
程序可以按照以下方式显示
#include <stdio.h>
int main(void)
{
char c;
do
{
printf( "Enter a character ('x' - exit): " );
} while ( scanf( " %c", &c ) == 1 && c != 'x' );
return 0;
}