我尝试理解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) - > ...
我明白这是对的吗? (抱歉,英语不是我的母语)
问候
答案 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功能
[...]
- 由白色空格字符组成的指令通过读取第一个非空白字符(保持未读)的输入来执行,直到不再能读取字符为止。该指令永远不会失败。
醇>
这意味着执行仍然在%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功能
[...]
- 跳过输入空白字符(由
醇>isspace
函数指定),除非规范包含[
,c
或n
说明符。 284
答案 1 :(得分:1)
差不多。
Scanf读取输入缓冲区(stdin)。
在windows cmd.exe终端中按Enter键将您输入的输入刷新到输入缓冲区中,提示您填写第一个变量。
然后再次提示,填写第二个变量。