2016-05-12 6 views
4

私は数字がいっぱいの1列のファイルを持っているので、すべてのファイルを集計したい。問題は、無効なデータが見つかるとすぐに終了することです(fprintfが失敗するとすぐに終了することができます)。複数のファイルを読むときに読書を停止する(gotoを使わない)

gotoを使用して最初の試みは(とthis answerに触発さ)私はよりよい解決策を(すなわちgotowhile(1)を使用していない!)見て喜んだろう次

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]); 

です。私は多くの旗をセットして汚れたままにしておきたい。

+4

この質問はおそらくStackOverflowではなくhttp://codereview.stackexchange.com/の良い候補です。 – Leandros

+2

int is_ok = 1; while(is_ok){body; if(失敗)is_ok = 0; } –

答えて

7

なぜですか?

完全に有効な使用例はgotoです。それは最も読みやすい解決策であり、その仕事をしています。それを変えるのはどうしてですか?

+0

問題ありません。私はただ私のオフィスに猛禽が欲しいと思っている;) – styko

+0

Downvoter、説明に気を付けろ? – Leandros

2

あなたは次のことを試すことができます:ここで、あなたが学習運動としてgotoのこの完全に合法的な使用を避けたいと仮定すると、

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]); 
+0

@dasblinkenlight例を変更しました – GMichael

+0

コードがあまりに多く印刷されました。内側ループの繰り返しごとに1回、OPの外側ループの繰り返しごとに1回印刷されます。 – dasblinkenlight

+0

はい、そうです。問題は、この場合2つのループの必要性を理解していないことです。 – GMichael

4

は、あなたがそれを行うことができる方法である:ループ終了を示すフラグ変数を作ります、内側のループでそれを設定し、すべてのループでそれを確認してください。

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は条件付きで保護する必要があるため。

もう1つのトリックは、1つのループで書き換え、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]); 
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]); 
0

大きな出口ジャンプが必要なときは、通常ループを関数にカプセル化します

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); 

などを使用することを暗示します。通常、コードの読み取りにも役立ちます。

関連する問題