OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

すっきりかくには?

  • 暇なときにでも
  • 質問No.196180
  • 閲覧数43
  • ありがとう数4
  • 気になる数0
  • 回答数5
  • コメント数0

お礼率 62% (23/37)

xyn[10][1000]に数値データが入っています。
それを横100個×縦100個の形に出力してカンマをつけたい。

programの一部を抜き出しました。
一応目的どおり動くのですが、もう少しすっきりした書き方を
するためにはどのような方法がありますか?

FILE *fp2;
if((fp2 = fopen("res.dat", "w")) == NULL)
{
fprintf(stderr, "出力ファイルを開けません\n");
return 1;
}

for(i=0;i<100;i++)fprintf(fp2,"%d ,",i);//番号
for(k=0;k<10;k++){
for(i=0;i<1000;i++){
if(i==100)fprintf(fp2,"\n");
if(i==200)fprintf(fp2,"\n");
if(i==300)fprintf(fp2,"\n");
if(i==400)fprintf(fp2,"\n");
if(i==500)fprintf(fp2,"\n");
if(i==600)fprintf(fp2,"\n");
if(i==700)fprintf(fp2,"\n");
if(i==800)fprintf(fp2,"\n");
if(i==900)fprintf(fp2,"\n");
fprintf(fp2,"%f ,",xyn[i][k]);
}fprintf(fp2,"\n");
}

よろしくお願いします。
通報する
  • 回答数5
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.5
レベル12

ベストアンサー率 48% (325/664)

No.1の回答をしたhitomuraです。
最初の書き込みでは時間がなかったため、なぜそう変更したかかけませんでした。
と、いうわけで、ちょっと解説を。

あなたのコードでは、今まで書き込んだデータ個数が100の倍数かどうか判定(およびもしそうなら改行処理)をし、その後データを書き込んでいます。
しかし、書き込みの直後、今書き込んだデータが100の倍数番目かどうかを判定したほうが自然ではないでしょうか?
その方針に従い、
(1)if文をデータ書き込み文の後ろに移動、
(2)今の書き込み個数を求めるため判定する数をi→i+1に変更
(3)「100の倍数」を表すため、剰余演算子を使用
という変更をしました。

…しかし、この方法にも問題がありまして…

それは、(3)の変更です。この変更だと、各ループごとに必ず剰余を求めなくてはならず、その分処理が遅くなります。
#まあ、ファイルへの出力速度からすると微々たるものですが…

と、いうわけで、ループ内の計算回数を極力減らす方針でもう1度書きなしてみました。

for(k=0;k<10;k++){
 for(i=0;i<1000;i++){
  if(i==100)fprintf(fp2,"\n");
  if(i==200)fprintf(fp2,"\n");
  if(i==300)fprintf(fp2,"\n");
  if(i==400)fprintf(fp2,"\n");
  if(i==500)fprintf(fp2,"\n");
  if(i==600)fprintf(fp2,"\n");
  if(i==700)fprintf(fp2,"\n");
  if(i==800)fprintf(fp2,"\n");
  if(i==900)fprintf(fp2,"\n");
  fprintf(fp2,"%f ,",xyn[i][k]);
 }fprintf(fp2,"\n");
}

for(i=0;i<10;i++){
 for(j=0;j<10;j++){
  int k = j * 100;
  int k_boundaly = k + 100;
  for ( /* k:初期化済み */; k < k_boundaly; k++ ){
   fprintf(fp2,"%f ,",xyn[i][k]);
  }
  fprintf(fp2,"\n");
 }
}

今度のは、100個のデータ出力および改行出力をひとまとめにして行い、それを10回行う(これで計1000個)、さらにそれらを全体で10回行う、という方針になります。
お礼コメント
hgdream

お礼率 62% (23/37)

詳しく解説していただき、ありがとうございました。
投稿日時 - 2002-01-11 23:08:06
-PR-
-PR-

その他の回答 (全4件)

  • 回答No.1
レベル12

ベストアンサー率 48% (325/664)

このようにしてみては? for(k=0;k<10;k++){  for(i=0;i<1000;i++){   if(i==100)fprintf(fp2,"\n");   if(i==200)fprintf(fp2,"\n");   if(i==300)fprintf(fp2,"\n");   if(i==400 ...続きを読む
このようにしてみては?
for(k=0;k<10;k++){
 for(i=0;i<1000;i++){
  if(i==100)fprintf(fp2,"\n");
  if(i==200)fprintf(fp2,"\n");
  if(i==300)fprintf(fp2,"\n");
  if(i==400)fprintf(fp2,"\n");
  if(i==500)fprintf(fp2,"\n");
  if(i==600)fprintf(fp2,"\n");
  if(i==700)fprintf(fp2,"\n");
  if(i==800)fprintf(fp2,"\n");
  if(i==900)fprintf(fp2,"\n");
  fprintf(fp2,"%f ,",xyn[i][k]);
 }fprintf(fp2,"\n");
}

for(k=0;k<10;k++){
 for(i=0;i<1000;i++){
  fprintf(fp2,"%f ,",xyn[i][k]);
  if((i+1)%100==0)fprintf(fp2,"\n");
 }
}


  • 回答No.2
レベル11

ベストアンサー率 28% (122/425)

プログラムをすっきりさせるには、ロジックを構成する物を良く考えると良いと思います。 数学の、式を纏めるのと似てますね。 先ず、同じ値を比較する場合は、if文を使うよりも、Switchi文を使う方が良いです。 この例ですと、 if(i==100)fprintf(fp2,"\n");    ・    ・    ・ if(i==900)fprintf(fp2,& ...続きを読む
プログラムをすっきりさせるには、ロジックを構成する物を良く考えると良いと思います。

数学の、式を纏めるのと似てますね。

先ず、同じ値を比較する場合は、if文を使うよりも、Switchi文を使う方が良いです。

この例ですと、
if(i==100)fprintf(fp2,"\n");
   ・
   ・
   ・
if(i==900)fprintf(fp2,"\n");

となってる部分を、
switch(i){
  case 100:fprintf(fp2,"\n"); break;
   ・
   ・
   ・
  case 900:fprintf(fp2,"\n"); break;
}
とします。

しかし、もっと良く見てみると、全ての所でやってる事が一緒ですね?
そういう場合は、
switch(i){
  case 100:
   ・
   ・
   ・
  case 900:fprintf(fp2,"\n"); break;
}
とすれば、良いのです。

しかし、もっと良く見ると比較する値にも法則がありますね。
計算式に直して見ましょう。
if((i%100)==0)fprintf(fp2,"\n");
と1行になってしまいました。

もっとすっきりさせるには、もっと大きな範囲から纏めて見れば良いと思いますよ。
お礼コメント
hgdream

お礼率 62% (23/37)

ありがとうございます。
投稿日時 - 2002-01-11 23:11:05
  • 回答No.3
レベル14

ベストアンサー率 24% (612/2465)

FILE *fp2; if( (fp2 = fopen("res.dat", "w")) == NULL) {  fprintf(stderr, "出力ファイルを開けません\n");  return 1; } for(i=0;i<100;i++){  fprintf(fp2,"%d ,",i ...続きを読む
FILE *fp2;
if( (fp2 = fopen("res.dat", "w")) == NULL)
{
 fprintf(stderr, "出力ファイルを開けません\n");
 return 1;
}

for(i=0;i<100;i++){
 fprintf(fp2,"%d ,",i);//番号
}
for(k=0;k<10;k++){
 for(i=0;i<1000;i++){
  if(i && !(i%100)){
   fprintf(fp2,"\n");
  }
  fprintf(fp2,"%f ,",xyn[k][i]);
 }
 fprintf(fp2,"\n");
}

#2の方の回答の
if(i%100==0)
だけでは、iが0のときに改行してしまいますので、ご注意ください。

また、プログラムはすっきりさせるだけでなく、後日変更時や後から見たときにもわかりやすくするために、if文での処理がたとえ1行であっても括弧を使うなどしたほうが良いです。バグの混入が減ります。

それと、fprintf(fp2,"%f ,",xyn[i][k]);ですが、iとkが逆になっています。転写時のミスでしょうか?

上記ソースには見栄えを整えるため、全角スペースを入れています。
コピー&ペーストする場合はご注意ください。
お礼コメント
hgdream

お礼率 62% (23/37)

ありがとうございます。
投稿日時 - 2002-01-11 23:10:03
  • 回答No.4
レベル11

ベストアンサー率 28% (122/425)

>iが0のときに改行してしまいますので、ご注意ください。 あら、ほんとですね。(^_^;;;大汗) madmanさん、ご指摘有難う御座います。m(_ _)m
>iが0のときに改行してしまいますので、ご注意ください。
あら、ほんとですね。(^_^;;;大汗)

madmanさん、ご指摘有難う御座います。m(_ _)m
このQ&Aのテーマ
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ