C 读取多个文件时停止读取(无goto)

C 读取多个文件时停止读取(无goto),c,C,我有一个单列数字的文件,我想总和所有的文件。问题是一旦发现无效数据(只要fprintf失败),就可以立即退出 第一次尝试使用goto(受启发)如下 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

我有一个单列数字的文件,我想总和所有的文件。问题是一旦发现无效数据(只要
fprintf
失败),就可以立即退出

第一次尝试使用
goto
(受启发)如下

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]);
while(1){
总和a=0;
对于(i=0;i为什么?


这是一个非常有效的“转到”用例。它是最具可读性的解决方案,可以完成任务。为什么要费心更改它?

您可以尝试以下方法:

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

for(i=0 ; i<N ;i++)
    fclose(infiles[i]);
int rc=1;
做
{
总和a=0;

对于(i=0;i假设您希望避免将
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]);
这可能看起来很难看(确实如此),但它又短又小:

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;
i=0;
而(1){
如果(fscanf(填充[i],%d\n,&a)!=1)中断;
和a+=a;
如果(++i对于(i=0;i当我需要一个大的退出跳转时,我通常将循环封装到一个函数中,并简单地使用
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);
void read(文件*[]填充,int N)
{
对于(;;){
总和a=0;

对于(i=0;看,那么没问题。我只是不希望办公室里有猛禽;)这个问题可能是一个很好的候选,而不是StackOverflow。int是_ok=1;而(is_ok){body;if(fail)是_ok=0;}@dasblinkenlight我修改了示例现在你的代码打印太多了-内循环每次迭代打印一次,而OP的代码则是外循环每次迭代打印一次。是的,你是对的。问题是我不理解在这种情况下需要两个循环。OP读取
N
文件,直到其中一个文件用完。此时,他停止所有读取谢谢。现在我看到了。
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]);
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);