阅读mutliple文件时停止阅读(不带goto)

时间:2016-05-12 09:21:21

标签: c

我的文件只有一列数字,我想要汇总所有文件。问题是能够在找到无效数据后立即退出(只要fprintf失败)。

使用goto(受this answer启发)的第一次尝试是以下

while(1) {
    sum_a = 0;
    for(i=0 ; i<N ;i++){
        if(fscanf(infiles[i], "%d\n", &a) != 1){
            goto end; // yeah, I know...
        }
        sum_a += a;
    }
    printf("%d\n", sum_a); // Should NOT be read if anything failed before
}

end:
for(i=0 ; i<N ;i++)
    fclose(infiles[i]);

我很高兴看到一个更好的解决方案(即不使用gotowhile(1)!)。我不想弄乱许多标志,并以肮脏的方式解开。

5 个答案:

答案 0 :(得分:7)

<强>为什么吗

这是goto完全有效的用例。它是最易读的解决方案,并且完成了这项工作。为什么要改变呢?

答案 1 :(得分:4)

假设您希望避免使用FreeMarkerConfigurer完全合法地使用goto作为学习练习,请按以下步骤操作:创建一个表示循环终止的标志变量,将其设置在内部循环中,然后检查它在所有循环中:

int stop = 0;
while(!stop) {
    sum_a = 0;
    for(i=0 ; i<N ;i++){
        if(fscanf(infiles[i], "%d\n", &a) != 1){
            stop = 1;
            break;
        }
        sum_a += a;
    }
    if (!stop) {
        printf("%d\n", sum_a);
    }
}
for(i=0 ; i<N ;i++)
    fclose(infiles[i]);

请注意您的代码如何立即变得不易读,因为printf需要受条件保护。

另一个技巧是使用单个循环重写并使用break停止。可读性不会受到太大影响:

int i = 0;
for (;;) { // This "forever" loop is idiomatic in C
    if(fscanf(infiles[i], "%d\n", &a) != 1) {
        break;
    }
    sum_a += a;
    if (++i == N) {
        printf("%d\n", sum_a);
        i = 0;
    }
}
for(i=0 ; i<N ;i++)
    fclose(infiles[i]);

答案 2 :(得分:2)

您可以尝试以下操作:

OpenCV

答案 3 :(得分:0)

这个可能看起来很丑陋(它是),但它很短且很小:

sum_a = 0;
i =0;
while(1) {
        if(fscanf(infiles[i], "%d\n", &a) != 1) break;
        sum_a += a;
        if (++i < N) continue;
        printf("%d\n", sum_a);
        break;
        }

for(i=0 ; i<N ;i++)
    fclose(infiles[i]);

可能有点不那么难看:

sum_a = 0;
for(i=0 ; i<N ;i++){
    if(fscanf(infiles[i], "%d\n", &a) != 1) break;
    sum_a += a;
    }

if (i == N) printf("%d\n", sum_a);

for(i=0 ; i<N ;i++)
    fclose(infiles[i]);

答案 4 :(得分:0)

当我需要一个大的退出跳转时,我通常将循环封装到一个函数中并简单地使用return,例如:

void read(FILE*[] infiles, int N)
{
    for(;;) {
        sum_a = 0;
        for(i=0 ; i<N ;i++){
            if(fscanf(infiles[i], "%d\n", &a) != 1){
                return;
            }
            sum_a += a;
        }
        printf("%d\n", sum_a);
    }
}

void cleanup(FILE*[] infiles, int N)
{
    for(i=0 ; i<N ;i++)
        fclose(infiles[i]);
}

read(infiles, N);
cleanup(infiles, N);

它通常也有助于阅读代码。