- ベストアンサー
行の操作
ファイルから行を読み込み、それに順じて行をソートするプログラムを作りたいのですが、ちょっと混乱しています。ファイルは、以下のようになっています。 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); }
- みんなの回答 (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;の後に記述されているので、実行されない) 以上の注意点を理解した上で、立派なプログラム屋さんとして成長していって下さい。
その他の回答 (5)
- kokorone
- ベストアンサー率38% (417/1093)
すみません。#1です。先ほどの発言は、 #1です。#2さん、失礼しました。
- kokorone
- ベストアンサー率38% (417/1093)
#1,#2です。失礼しました。 sor++としてしまっては、sorの位置がずれて いってしまいますよね。 そこで、sor[i];とやっても、更新されたsor が基準になってしまいますね。 やはり、 j=0; while (fgets(line ,15, qqq) != NULL) { sscanf(line,"%s %f",name ,(sor+j)); j++; } としてみてください。 sorのポインタは、更新しないようにしてください。
お礼
ありがとうございました。
- buihyaku
- ベストアンサー率29% (97/326)
よく考えたら、sorポインタを進めてしまってはあとで困りますね。それからsscanfはdouble値で受けるのなら %fではなく%lfが正解のようです。 double *sorptr = sor; /* 最初の位置を覚える */ while (fgets(line ,50, qqq) != NULL) { sscanf(line,"%s %lf",name ,sorptr++); } これでどうでしょうか?
お礼
ありがとうございました。lfにすべきでした。
- buihyaku
- ベストアンサー率29% (97/326)
読んでもいまひとつよくわからないのですが、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は捨てられてしまってますがよいのでしょうか。。
お礼
ご指摘ありがとうございます。確かにnameもmallocして格納すべきだと思います。sorはdoubleの値を格納するための配列です。また、Yは全行数です。未だに0が格納されてしまいます・・・。
- kokorone
- ベストアンサー率38% (417/1093)
sscanf(); ですが、sorを使っていますが、whileループ 内でポインタの更新がされていないため、 毎回、sorの先頭に書き込んでしまいます。 また、Yも定義されていませんね。 int Y; -------------------- Y=0; while (fgets(line ,15, qqq) != NULL) { sscanf(line,"%s %f",name ,sor++); Y++; } としてください。
お礼
ありがとうございます。Yはdefineで定義していて、全行数です。一応プログラムは回るようになったのですが、全て0になってしまいます・・・。
お礼
ようやくできました。ありがとうございます。やはりメモリはfreeで解放すべきだと思います。