C:for 循环与 scanf 的行为真的很奇怪

标签 c loops for-loop scanf

所以我得到了以下代码:

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 , 但由于输入流中没有其他内容,因此不会分配 xy ,因此它返回值 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/

相关文章:

c - 使用 ncurses 编写文本

JavaScript 在 for 循环中生成包含 <li> 内容的 HTML <ul> 列表

Java 的 for 循环问题

java - 用 Java 数组中的特殊字符替换用户输入中的元音

c - 关于IP包的空字段

c - 从文件崩溃读取时使用 realloc 扩展缓冲区

循环内的 JavaScript 闭包 – 简单的实际示例

python-3.x - for循环中的“unexpected EOF while parsing”?

c - *预期为 'int *',但参数的类型为 'int **' * c 中的警告

循环内的 JavaScript 闭包 – 简单的实际示例