关于scanf读入的问题
  • 板块灌水区
  • 楼主shaoyifan
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/12/11 12:14
  • 上次更新2023/11/3 22:30:47
查看原帖
关于scanf读入的问题
505544
shaoyifan楼主2021/12/11 12:14

这是一个关于scanf读入的问题

问题来源于蓝书381. 有线电视网络

输入格式

输入包含多组测试数据。

每组数据占一行,首先包含两个整数 n 和 m,接下来包含 m 对形如 (x,y) 的数对,形容点 x 与点 y 之间有一条边。

数对 (x,y) 中间不会包含空格,其余地方用一个空格隔开。

这是AC代码

/*省略网络流和头文件*/

int main() {
    while (scanf("%d%d", &n, &m) != EOF) {
        init();

        for (int i = 1; i <= m; ++ i) {
            int a, b;
            scanf(" (%d,%d)", &a, &b); // 这是正确的写法,可以AC
            /*
                scanf("(%d,%d)", &a, &b);
                scanf("(%d,%d) ", &a, &b);
                而这两种写法都不对
            */
            a ++, b ++;
            add(a + n, b, INF);
            add(b + n, a, INF);
            g[a][b] = g[b][a] = true;
        }
        for (int i = 1; i <= n; ++ i) add(i, i + n, 1);
        memcpy(fs, f, sizeof f);

        int res = n;
        for (S = n + 1; S <= 2 * n; ++ S)
            for (T = S - n + 1; T <= n; ++ T)
                if (!g[S - n][T]) {
                    memcpy(f, fs, sizeof f);
                    res = min(res, dinic());
                }

        printf("%d\n", res);
    }
}

接下来我对过程进行输出发现一些奇怪的东西

输入:

0 0
1 0
3 3 (0,1) (0,2) (1,2)
2 0
5 7 (0,1) (0,2) (1,3) (1,2) (1,4) (2,3) (3,4)

scanf("(%d,%d)", &a, &b); 的读入

调试代码:

while (scanf("%d%d", &n, &m) != EOF) {
    printf("现在是第%d次读入 n: %d, m: %d\n", times ++, n, m);
    for (int i = 1; i <= m; ++ i) {
        int a, b;
        scanf("(%d,%d)", &a, &b);
        printf("(%d,%d)%c", a, b, " \n"[i == m]);
    }
}

输出:

现在是第1次读入 n: 0, m: 0
现在是第2次读入 n: 1, m: 0
现在是第3次读入 n: 3, m: 3
(-64540416,21938) (-64540416,21938) (-64540416,21938)
现在是第4次读入 n: 3, m: 3
(0,1) (0,1) (0,1)
现在是第5次读入 n: 3, m: 3
(0,2) (0,2) (0,2)
现在是第6次读入 n: 3, m: 3
(1,2) (1,2) (1,2)
现在是第7次读入 n: 2, m: 0
现在是第8次读入 n: 5, m: 7
(1,2) (1,2) (1,2) (1,2) (1,2) (1,2) (1,2)
现在是第9次读入 n: 5, m: 7
(0,1) (0,1) (0,1) (0,1) (0,1) (0,1) (0,1)
现在是第10次读入 n: 5, m: 7
(0,2) (0,2) (0,2) (0,2) (0,2) (0,2) (0,2)
现在是第11次读入 n: 5, m: 7
(1,3) (1,3) (1,3) (1,3) (1,3) (1,3) (1,3)
现在是第12次读入 n: 5, m: 7
(1,2) (1,2) (1,2) (1,2) (1,2) (1,2) (1,2)
现在是第13次读入 n: 5, m: 7
(1,4) (1,4) (1,4) (1,4) (1,4) (1,4) (1,4)
现在是第14次读入 n: 5, m: 7
(2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3)
现在是第15次读入 n: 5, m: 7
(3,4) (3,4) (3,4) (3,4) (3,4) (3,4) (3,4)

scanf竟然读了15次 其中对于m != 0的行都读入了不止一次 观察其中的a, b发现a, b的数值在有些输入中根本没有改变

scanf("(%d,%d) ", &a, &b); 的读入

调试代码:

while (scanf("%d%d", &n, &m) != EOF) {
    printf("现在是第%d次读入 n: %d, m: %d\n", times ++, n, m);
    for (int i = 1; i <= m; ++ i) {
        int a, b;
        scanf("(%d,%d) ", &a, &b);
        printf("(%d,%d)%c", a, b, " \n"[i == m]);
    }
}

输出:

现在是第1次读入 n: 0, m: 0
现在是第2次读入 n: 1, m: 0
现在是第3次读入 n: 3, m: 3
(-2099347200,21855) (-2099347200,21855) (-2099347200,21855)
现在是第4次读入 n: 3, m: 3
(0,1) (0,2) (1,2)
现在是第5次读入 n: 2, m: 0
现在是第6次读入 n: 5, m: 7
(1,2) (1,2) (1,2) (1,2) (1,2) (1,2) (1,2)
现在是第7次读入 n: 5, m: 7
(0,1) (0,2) (1,3) (1,2) (1,4) (2,3) (3,4)

这样读入也有同样的问题,但是重复的次数少了

scanf(" (%d,%d)", &a, &b); 的读入

调试代码:

while (scanf("%d%d", &n, &m) != EOF) {
    printf("现在是第%d次读入 n: %d, m: %d\n", times ++, n, m);
    for (int i = 1; i <= m; ++ i) {
        int a, b;
        scanf(" (%d,%d)", &a, &b);
        printf("(%d,%d)%c", a, b, " \n"[i == m]);
    }
}

输出:

现在是第1次读入 n: 0, m: 0
现在是第2次读入 n: 1, m: 0
现在是第3次读入 n: 3, m: 3
(0,1) (0,2) (1,2)
现在是第4次读入 n: 2, m: 0
现在是第5次读入 n: 5, m: 7
(0,1) (0,2) (1,3) (1,2) (1,4) (2,3) (3,4)

这样读入就是正确的

几个问题

  1. 关于 c++ 中scanf究竟是怎么实现的,为什么同样的数据可以重复读入,以上的情况究竟为什么会发生
  2. scanf参数中格式控制字符中加入 空格"(),[].{}" 对读入有什么影响
  3. 对于这样的较为复杂的输入有没有什么比较容易读入方式
2021/12/11 12:14
加载中...