所以我得到了以下代码:
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
那里发生了什么?第一行上方还有其他输出代码,来自程序的另一部分。这可能是造成这种情况的原因吗?
最佳答案
不同于%s
, %d
, %f
,以及大多数其他转换说明符,%c
转换说明符不会跳过任何前导空格,因此它会从上一个条目中获取换行符。
在您键入 a 1 1 <Enter>
之后,输入流的内容是{'a', '1', '1', '\n'}
.第一个scanf
消耗 a
, 1
, 和 1
, 留下尾随 \n
在输入流中。 scanf
返回 3 并打印 q
的值.
第二次循环,scanf
捡起剩下的 \n
并将其分配给 l
, 但由于输入流中没有其他内容,因此不会分配 x
或 y
,因此它返回值 1 并且您的分支未被采用。然后循环再次开始。
解决此问题的最简单方法是在格式字符串中的 %c
之前放置一个前导空格转换说明符:
if (3 == scanf(" %c %d %d", &l, &x, &y))
printf("%d\n", q);
格式中的前导空格将导致 scanf
跳过输入流中的任何前导空格,这样您就不会不小心从上一个条目中拾取尾随换行符。当然,如果您想要选择任何空白字符,您将不得不做一些不同的事情。
关于C:for 循环与 scanf 的行为真的很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9822496/