最新閲覧日:

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

よろしくお願いします。

A 回答 (5件)

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回行う、という方針になります。
    • good
    • 0
この回答へのお礼

詳しく解説していただき、ありがとうございました。

お礼日時:2002/01/11 23:08

>iが0のときに改行してしまいますので、ご注意ください。


あら、ほんとですね。(^_^;;;大汗)

madmanさん、ご指摘有難う御座います。m(_ _)m
    • good
    • 0

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が逆になっています。転写時のミスでしょうか?

上記ソースには見栄えを整えるため、全角スペースを入れています。
コピー&ペーストする場合はご注意ください。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2002/01/11 23:10

プログラムをすっきりさせるには、ロジックを構成する物を良く考えると良いと思います。



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

先ず、同じ値を比較する場合は、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行になってしまいました。

もっとすっきりさせるには、もっと大きな範囲から纏めて見れば良いと思いますよ。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2002/01/11 23:11

このようにしてみては?


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");
 }
}
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このカテゴリの人気Q&Aランキング

おすすめ情報

カテゴリ