- ベストアンサー
テキストファイルからの読み込みがうまくできません(>_<)
C言語初心者の学生です。 読んでいただきありがとうございます。 テキストファイルに数字を並べ、それを読み込んで char型の変数に入れ、さらにatofによってfloat型に変換し、計算に使っていくということがしたいのですが、 テキストファイルの書き方がおかしいのか、プログラムの書き方がおかしいのか、テキストファイルに書いたとおりの値とは異なるおかしな値が表示されます・・・ だいたいのプログラムの書き方は、 char型のa2、float型のa[n][n]、FILE *fpINを定義して if ( (fpIN = fopen("matrix.txt", "r" )) != NULL ){ if ( fgets(a2,sizeof(a2),fpIN) != NULL ){ } fclose( fpIN ); } for(i=0;i<n;i++){ for(j=0;j<n;j++){ a[i][j]=atof(a2); } } というようなものです。 テキストファイルは、数字をカンマで区切ったり、スペースで区切ったりと いろいろ試してみたのですが、やはり書き込んだ値とは異なるものが表示されます・・・ 最終的には、ひとつのテキストファイルに 複数の行列のための値を書き込んでおき、それを読み込んで計算させるということをしたいのです・・・ どなたか、正しく値が読み込まれない原因が分かりましたら、教えていただければと思います。 お手数をおかけしてすみませんが、よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
★それではアドバイスします。 ・最初に a2[] 配列の容量(サイズ)が足りません。 テキストファイルでは 19 バイトほどあります。 n が 3 なので a2[3*3] はサイズが不足しています。 行列が 3x3 だけなら a2[ 32 ] あれば十分ですが 100x100 なども考えると容量が不足します。 そこで fgets() 関数ではなく fscanf() 関数を利用してみてはどうでしょうか。 ・下にそのサンプルを載せておきます。 サンプル: if ( (fp = fopen("matrix.txt","r")) != NULL ){ for ( j = 0 ; j < N ; j++ ){ for ( i = 0 ; i < N ; i++ ){ if ( fscanf(fp,"%lf,",&a[j][i]) != 1 ){ goto LoopExit; } } } LoopExit: fclose( fp ); } その他: ・上記のサンプルは読み込み部分です。 表示の部分はあっています。 ・a[][] の二次元配列は a[縦方向][横方向] という感じで代入しています。 参照の時もそうして下さい。 ・以上。
その他の回答 (3)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 1,2,3,4,5,6,7,8,9 > と 書きました。 ならば - 文字列として読み込み - ','を区切りに分割し - 分割されたそれぞれの文字列を数値に変換 しなければなりません。 # fgetsで一気に取り込むなんて誰に教わった!? # それができるのはバイナリファイルのみ。
お礼
fgetsによる取り込みがバイナリファイルのみというのは 今言われてみて納得しました!わたしは情報系を専攻しているわけでなく研究でプログラムを利用しているためC言語は 本当に基礎的なこと意外は独学で身につけました。そのため、誰に教わったということもなく、苦手な分野があり、特にファイルの入出力が今 苦手としています。 ファイルからの取り込みで、fgetsで読み込んでいるプログラムを目にしたので、fgetsは常に読みこみに使える(一行ずつ読み込む)ものだと思い込んでおりましたが、確かに あれはバイナリ形式でした(>_<) まだ 全てのコマンドを 把握しきれているわけではないので、奮闘しております。 アドバイスありがとうございました!
- Oh-Orange
- ベストアンサー率63% (854/1345)
★ソースが省略しすぎでないの? >どなたか、正しく値が読み込まれない原因が分かりましたら、教えていただければと思います。 ↑ 質問の大体のプログラムの書き方だけでは原因が分かりませんが…。 特に fgets() 関数のブロック内が重要でしょうからそこは省略しない方が良いです。 どんな感じなのでしょうか? ・あと for 文で i, j を使っていますが、a[i][j]=atof(a2); だけではいつも同じ値が a[i][j] に代入されると思います。fgets() 関数で a2[] 配列の数字列を読み込んで いるようですがカンマか、スペースなどで区切られているのなら atof() で位置を変更 すべきです。つまり、 a2[] = "123,456,789"; の文字列がセットされているのならば a[i][0] = atof( a2 + 0 ); a[i][1] = atof( a2 + 4 ); a[i][2] = atof( a2 + 8 ); という感じにします。 引数で与える位置がいつも同じなので a[i][j] にはいつも同じ値がセットされていませんか? >お手数をおかけしてすみませんが、よろしくお願いします。 ↑ main() のソースを補足に貼り付けて下さい。 あとテキストデータの内容は回答者 No.1 さんの補足にでも貼り付けておいて下さい。 分かりやすいように。 ・それでは。また。
補足
すみません、要点部分しか書いておらず、説明不足で失礼いたしました(>_<)作ろうとしているプログラムは長ったらしかったので、シンプルに 今のわたしが勘違いをしたままの知識でではありますが、テキストファイルから数値を読み込んでパネルに表示する というだけのものを書いてみました。それがこちらです。 #include<stdio.h> #include<stdlib.h> #define n 3 main(){ int i,j; char a2[n*n]; double a[n][n]; FILE *fp; fp = fopen("matrix.txt", "r" ); fgets(a2,sizeof(a2),fp); fclose(fp); for(i=0;i<n;i++){ for(j=0;j<n;j++){ a[i][j]=atof(a2); printf("%10.2f",a[i][j]); } printf("\n"); } return 0; } テキストファイルは 1,2,3,4,5,6,7,8,9 EOF としました。なので、ご指摘のとおり、行列にはすべて1.0がはいってしまっているようです(>_<) ココを書いたあと、今ご指摘いただいたところを 確認してみます!
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
書き込まれたテキストファイルのサンプルを示してください。
補足
そうですね、すみません! 3×3の行列の要素を書きたいので 1,2,3,4,5,6,7,8,9 EOF と 書きました。説明不足ですみませんでした!
お礼
ご親切に ありがとうございます! たった今 きちんと読み込むことができました!! 本当にありがとうございます! とりあえず基礎が分かったところで、応用にむけて頑張ってみます。 さきほどもどこかで書いたかもしれませんが、 二つ分の行列の要素をあるひとつのファイルに与えておきそこから読み込みたいと思っています。 今教えていただいた基礎をもとに 考えてみようと思いますが、もしもまた埒があかないようでしたら 失礼するかもしれません(>_<) ひとまず、ありがとうございました!