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