• ベストアンサー

行の操作

ファイルから行を読み込み、それに順じて行をソートするプログラムを作りたいのですが、ちょっと混乱しています。ファイルは、以下のようになっています。 abcedf 0.53343 efghij 0.09473 klmnop 0.23453 . . . これをスコアとして行ごとに並べ替えようと思っています。以下のようなプログラムを考えたのですが、まず配列の格納がうまくいきません。よろしくお願いします。 main(){ int i, j; char line[50], name[50]; double *sor,tmp; FILE *qqq; sor=(double*)malloc(sizeof(int*)*Y); qqq = fopen("score_sort.txt","r"); //行単位の操作 while (fgets(line ,15, qqq) != NULL) { sscanf(line,"%s %f",name ,sor); } for(i=0;i<Y;i++) printf("sor[%d]=%f\n",i,sor[i]); return 0; fclose(qqq); }

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

  • ベストアンサー
回答No.6

こんばんは。yasuyuki007と申します。 C言語において、「ポインタと配列は自由に混同しても問題無い」という格言?があります。 これを使用すると、yuji221さんの質問に対する回答としては、以下の通りです。 //行単位の操作 j = 0; while (fgets(line, sizeof(line), qqq) != NULL) {  sscanf(line, "%s %lf", name, &sor[j]);  j++; } 以下は、yuji221さんのプログラムを読んでいて、ちょっと気になった点についてアドバイスしておきます。 (仕事でプログラムを作成している、現役プログラマ(10年戦士)の視点から見てです) ・fgetsにおいて、バッファサイズを直接記述するのはよろしくない。(後々の保守において、バッファサイズが変更になった際に、修正箇所が増えてしまう) ⇒修正箇所が増えるに従って、バグ(プログラムミス)を作り込む可能性が高くなる。 ・mallocで確保したメモリを開放していない。 (OS側で自動開放してくれていればいいが、そうでないとメモリ不足となる可能性がある) ・オープンしたファイルがクローズされない。 (fclose(qqq);がreturn 0;の後に記述されているので、実行されない) 以上の注意点を理解した上で、立派なプログラム屋さんとして成長していって下さい。

yuji221
質問者

お礼

ようやくできました。ありがとうございます。やはりメモリはfreeで解放すべきだと思います。

その他の回答 (5)

  • kokorone
  • ベストアンサー率38% (417/1093)
回答No.5

すみません。#1です。先ほどの発言は、 #1です。#2さん、失礼しました。

  • kokorone
  • ベストアンサー率38% (417/1093)
回答No.4

#1,#2です。失礼しました。 sor++としてしまっては、sorの位置がずれて いってしまいますよね。 そこで、sor[i];とやっても、更新されたsor が基準になってしまいますね。 やはり、 j=0; while (fgets(line ,15, qqq) != NULL) { sscanf(line,"%s %f",name ,(sor+j)); j++; } としてみてください。 sorのポインタは、更新しないようにしてください。

yuji221
質問者

お礼

ありがとうございました。

  • buihyaku
  • ベストアンサー率29% (97/326)
回答No.3

よく考えたら、sorポインタを進めてしまってはあとで困りますね。それからsscanfはdouble値で受けるのなら %fではなく%lfが正解のようです。 double *sorptr = sor; /* 最初の位置を覚える */ while (fgets(line ,50, qqq) != NULL) { sscanf(line,"%s %lf",name ,sorptr++); } これでどうでしょうか?

yuji221
質問者

お礼

ありがとうございました。lfにすべきでした。

  • buihyaku
  • ベストアンサー率29% (97/326)
回答No.2

読んでもいまひとつよくわからないのですが、Yは全行数なのでしょうか?sorはdouble値の配列ですか? だとすると sor=(double*)malloc(sizeof(int*)*Y); は sor=(double*)malloc(sizeof(double)*Y); すべきでは? ポインタとdoubleではサイズが違いますのでこのままではメモリを壊します。 あとせっかく50文字バッファがとってあるのだからここはどかんと50でいきたいですね。 while (fgets(line ,50, qqq) != NULL) { sscanf(line,"%s %f",name ,sor++); } しかしsorは取れてもnameは捨てられてしまってますがよいのでしょうか。。

yuji221
質問者

お礼

ご指摘ありがとうございます。確かにnameもmallocして格納すべきだと思います。sorはdoubleの値を格納するための配列です。また、Yは全行数です。未だに0が格納されてしまいます・・・。

  • kokorone
  • ベストアンサー率38% (417/1093)
回答No.1

sscanf(); ですが、sorを使っていますが、whileループ 内でポインタの更新がされていないため、 毎回、sorの先頭に書き込んでしまいます。 また、Yも定義されていませんね。 int Y; -------------------- Y=0; while (fgets(line ,15, qqq) != NULL) { sscanf(line,"%s %f",name ,sor++); Y++; } としてください。

yuji221
質問者

お礼

ありがとうございます。Yはdefineで定義していて、全行数です。一応プログラムは回るようになったのですが、全て0になってしまいます・・・。

関連するQ&A