printf(“ Enter'a':”);在第一个循环后运行2次

时间:2019-09-24 12:41:55

标签: c char printf scanf

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次

3 个答案:

答案 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;
}