我的文件只有一列数字,我想要汇总所有文件。问题是能够在找到无效数据后立即退出(只要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]);
我很高兴看到一个更好的解决方案(即不使用goto
和while(1)
!)。我不想弄乱许多标志,并以肮脏的方式解开。
答案 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);
它通常也有助于阅读代码。