I have files with a single column full of numbers and I want to sum all the files. The problem is to be able to exit as soon as invalid data is found (as soon as fprintf fails).
A first attempt using goto (and inspired by this answer) is the following
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]);
I would glad to see a nicer solution (ie not using goto and while(1)!). I don't want to mess up with many flags set and unset in a dirty way.
Why?
It's a perfectly valid use case of goto. It's the most readable solution, and does the job. Why bother changing it?
Assuming that you wish to avoid this perfectly legitimate use of goto as a learning exercise, here is how you can do it: make a flag variable that indicates loop termination, set it in the inner loop, and check it in all loops:
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]);
Note how your code instantly became less readable, because printf needs to be protected by a conditional.
Another trick would be rewriting with a single loop and using break to stop. The readability would not suffer as much:
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]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With