读取数据并使用scanf跳过括号

3

我编写了一个C程序,从标准输入中读取数据。数据以数字开头,表示数据集的数量,接下来有N对数据,格式为(x y)。以下是我的代码:

#include <stdio.h>

int main()
{
    int n_sets;
    scanf("%d", &n_sets);
    int i;
    for(i = 0; i < n_sets; ++i)
    {
        int m, n;
        scanf("(%d %d)", &m, &n);
        printf("%d\t%d\n", m, n);
    }

    return 0;
}

但它不起作用。在输入数据集的编号后,程序直接打印未初始化的m&n。但是当我在(%d %d)前面添加一个空格时,它就可以正常工作了。有人能解释一下吗?


1
  1. 检查 scanf 的返回值。
  2. 使用调试器找出问题所在。
- Ed Heal
这让我想起了fflush()函数。 - Lucio
@Lucio:据我所记,fflush在stdin上是微软独有的扩展。 - zentrunix
我认为他可能在使用Windows。 - Lucio
@Lucio 它是平台无关的。Linux 和 Windows 有相同的结果。我对 scanf() 的行为不太清楚,verbose 的回答解释了这一点。 - jfly
4个回答

9
当您在scanf()的参数中有字符字面量时,它希望在格式字符串中找到这些字面量正如其所指定的那样。
scanf("%d", &n_sets);

正确读取 n_sets,并在缓冲区中的换行符或其他空格字符处停止。下一个 scanf()

scanf("(%d %d)", &m, &n);

希望在输入的开头找到一个左括号,但实际上却找到了一个空格字符。因此,它失败了,scanf() 没有读取任何内容就返回了。因此,你的 mn 保持未初始化状态,结果是垃圾值。

当你像这样在左括号前加入空格:

scanf(" (%d %d)", &m, &n);

这段代码中的scanf()函数告诉程序在输入缓冲区中跳过括号前的任何空格,以确保程序正常运行。


2
假设您的输入如下所示:

2 (1 2) (3 4)

第一个数字后面有一个空格(或者换行符?),因此需要在循环中将scanf更改为:
scanf("\n(%d %d)", &m, &n);
//     ^^

2

变更

scanf("%d", &n_sets);

to

scanf("%d\n", &n_sets);

输入你的n_sets,最后以[enter]结束,它就会生效。

enter image description here


请参考上面 verbose 的回答。他非常清楚地解释了发生了什么。 - Darwing
FYI:将“%d”更改为“%d\n”或“%d”或“%d\t”等都会产生相同的效果。在每种情况下,格式中的空格字符将匹配_任何_空格。 - chux - Reinstate Monica

1
似乎程序输入中有一些空格在您想要scanf解析的值之前。字符串中的空格告诉scanf忽略空格。没有它,scanf会立即寻找完全匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接