所以我有以下代码:
int q, x, y;
char l;
for (q = 0; q<10; q+=1) {
printf("%d\n", q);
if (3 == scanf("%c %d %d", &l, &x, &y)) {
printf("%d\n", q);
}
}
我希望这会运行“scanf”10次。每次在我输入任何东西之前打印'q',然后再打印。所以预期的输出应该是这个(如果我错了,请纠正我):
0
> a 1 1
0
1
> b 2 2
1
2
> c 3 3
2
...and so on.
但我真的明白了。
0
> a 1 1
1
1
2
> a 2 2
3
3
4
> a 3 3
5
5
6
> a 4 4
7
7
8
> a 5 5
9
9
如果我取出scanf功能,它会按照预期从0到9进行计数。 scanf函数发生了什么让for循环行为如此奇怪?我在Java / Python方面有一些经验,但我对C完全不熟悉。
根据您对此的评论编辑代码(为奇怪的格式化道歉):
for (q = 0; q<10; q+=1) {
printf("%d: ", q);
if (3 == scanf("%c %d %d ", &c, &x, &y)) printf("%d\n", q);
else { printf("WTF %d\n", q); }
}
一半解决了这个问题。它适用于第一个迭代的所有迭代。如此:
0: a 0 0
WTF 0
1: b 1 1
1
2: c 2 2
2
那里发生了什么?从程序的另一部分开始,在第一行之上还有其他输出代码。这会导致这种情况吗?
答案 0 :(得分:4)
你没有消耗“\ n”,getchar()会消耗它:
if (3 == scanf("%c %d %d", &l, &x, &y)) {
getchar();
printf("%d\n", q);
}
答案 1 :(得分:4)
与%s
,%d
,%f
以及大多数其他转换说明符不同,%c
转换说明符不会跳过任何前导空格,因此它会接收来自上一个条目的换行符。
输入a 1 1 <Enter>
后,输入流的内容为{'a', '1', '1', '\n'}
。第一个scanf
使用a
,1
和1
,在输入流中保留尾随\n
。 scanf
返回3并打印q
的值。
第二次循环,scanf
选择剩余的\n
并将其分配给l
,但由于输入流中没有其他内容,因此不会分配x
1}}或y
,因此它返回值1并且不执行分支。然后循环重新开始。
解决此问题的最简单方法是在%c
转换说明符之前的格式字符串中放置一个前导空格:
if (3 == scanf(" %c %d %d", &l, &x, &y))
printf("%d\n", q);
格式中的前导空格将导致scanf
跳过输入流中的任何前导空格,因此您不会意外地从上一个条目中获取尾随换行符。当然,如果你希望拿起任何空格字符,你就必须做些不同的事情。
答案 2 :(得分:2)
为什么不尝试在你的vars中添加else语句和printf来调试它? 似乎每次(3 == ..)都是真的,还有一次它是假的。 当您按Enter键时,scanf可能会为换行符运行两次...
答案 3 :(得分:0)
scanf函数返回不同的值而不是3(三个输入)。我不知道确切的原因,但我觉得因为scanf中的空格(“%c space%d”,&amp; c,&amp; i);函数它返回不同的值。