scanf in c和关系输入缓冲区

时间:2015-10-22 12:47:53

标签: c scanf

我尝试理解scanf和输入缓冲区之间的关系。我使用scanf使用以下格式字符串:

int z1,z2;
scanf("%d %d", &z1,&z2);

并尝试理解为什么我输入尽可能多的空格(Enter,Blanks,Tabs)后输入54之类的数字并按Enter键。

据我所知,我按下的每个键都放在输入缓冲区中,直到按Enter键。

因此,如果我键入54并按Enter键,则输入缓冲区包含3个元素,两个数字和换行符。所以我的缓冲区看起来像[5] [4] [\ n]

现在从左到右评估scanf / formatstring。所以第一个%d与54匹配,54存储在z1中。

由于格式字符串中的空格,因按下第一个输入而导致的换行符(\ n)被“消耗”。

所以在评估第一个%d和空格(\ n)后,缓冲区再次为空。

现在scanf尝试评估格式字符串中的第二个(和最后一个)%d。 因为缓冲区现在是空的,所以scanf等待进一步的用户输入(用户输入=从我的案例键盘中的stdin读取)。

所以缓冲状态/动作序列是

缓冲区为空 - > scanf的调用 - >用于用户输入的scanf块 - >用户输入为:54输入 - >缓冲区包含:[5] [4] [\ n] - >评估第一%d - >缓冲区包含[\ n] - >评估空白 - >缓冲空 - >用户输入的scanf块(因为评估了第二个和最后一个%d) - > ...

我明白这是对的吗? (抱歉,英语不是我的母语)

问候

2 个答案:

答案 0 :(得分:3)

  

据我所知,我按下的每个键都放在输入缓冲区中,直到按Enter键。

正确。按 Enter 将数据刷新到stdin(标准输入流)。请注意,它还会将\n发送到stdin

  

因此,如果我键入54并按Enter键,则输入缓冲区包含3个元素,两个数字和换行符。所以我的缓冲区看起来像[5] [4] [\ n]

  

现在从左到右评估scanf / formatstring。所以第一个%d与54匹配,54存储在z1。

右。

  

由于格式字符串中的空格,因按下第一个输入而导致的换行符(\ n)被“消耗”。

正确。

  

所以在评估第一个%d和空格(\ n)后,缓冲区再次为空。

  

现在scanf尝试评估格式字符串

中的第二个(和最后一个)%d

不完全。

两个%d之间的空格是whitespace character,格式字符串scanf中的空格字符指示scanf扫描并丢弃所有空白字符(如果有) 直到第一个非空白字符。这可以在n1570,C11标准的委员会草案中看到:

  

7.21.6.2 fscanf功能

     

[...]

     
      
  1. 由白色空格字符组成的指令通过读取第一个非空白字符(保持未读)的输入来执行,直到不再能读取字符为止。该指令永远不会失败。
  2.   

这意味着执行仍然在%d之间的空间中,因为它还没有遇到非空白字符。

  

因为缓冲区现在为空,scanf会等待进一步的用户输入(用户输入=从我的案例键盘中的stdin读取)。

所以,

  

缓冲区为空 - > scanf的调用 - >用于用户输入的scanf块 - >用户输入为:54输入 - >缓冲区包含:[5] [4] [\ n] - >评估第一%d - >缓冲区包含[\ n] - >评估空白 - >缓冲空 - >用于用户输入的scanf块(由于评估了第二个和最后一个%d) - > ...

应该是

“缓冲区为空 - >调用scanf - > scanf阻止用户输入 - >用户输入为:54\n - >缓冲区包含:{{ 1}} - >评估第一个54\n - >缓冲区包含%d - >评估空白 - >缓冲区空 - > scanf块用于用户输入(因为评估空白) - > ......“

请注意,当\n s之前(scanf之前)%d之前有%d个空白字符或空白字符时,%d的行为方式相同跳过领先的空白字符。实际上,对于空格字符很重要的唯一格式说明符是%c%[%n,如n1570所示:

  

7.21.6.2 fscanf功能

     

[...]

     
      
  1. 跳过输入空白字符(由isspace函数指定),除非规范包含[cn说明符。 284
  2.   

答案 1 :(得分:1)

差不多。

Scanf读取输入缓冲区(stdin)。

在windows cmd.exe终端中按Enter键将您输入的输入刷新到输入缓冲区中,提示您填写第一个变量。

然后再次提示,填写第二个变量。