• ベストアンサー

c言語:ファイルの入出力

2つの行列をファイルから読み込み、その積をファイルに出力するプログラムを 作りたいのですが、参考書を読んでもよくわからないので教えて頂きたいです。 テキストファイルの文字列のコピーなどは、参考書を見てできたのですが、 ファイル入出力を使った数値の計算がいまいち理解できませんでした。 注意点は以下の通りです。 ・ファイルはカンマ区切りのテキストファイルとし、入力ファイルはエクセルで作成。拡張子は.csv。 ・ファイル名はキーボードから入力できるようにする。 よろしくお願いします。

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

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

このままだと単なる「丸投げ」についての回答になってしまいますので、まず確認です。 Q1. キーボードからの文字入力については理解できていますか? (文字、数字などを入力して画面表示されるなど) Q2. ファイルの入出力ついてはどの程度理解されていますか? (ファイルのオープン/クローズ、データの読み込み、書き込みなど) 処理のキモとなるのは上記のの部分です。 まず、上記をどの程度理解しているかを確認したいです。 また、上記がわからなくても、それ以外「行列から積を求める」部分については過去の質問から作成できると判断しています。 そのソースと、「ファイルの指定」「ファイルの読み書き」の処理が必要だと思われる個所について提示してみてください。

a0672113
質問者

補足

失礼極まりない質問の仕方をしてしまいしました。申し訳ございません。 ファイルの入出力に関しては始めたばかりで、完全に初心者です。 先輩から参考までに、と足し算の場合のプログロラムをいただきました。しかしこれをただデバッグすると、行列のサイズがNULLになります。もととなる2つの行列のデータ、名前はどのようにすれば良いのでしょうか?本当に基本的なことがわからなくて申し訳ないです。 #include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct matrix{ double *data; int size[2]; }MATRIX; //インプット関数 void input(MATRIX *matrix_A,MATRIX *matrix_B,char **argments) { FILE *fp=NULL; int i=0; int j=0; int k=0; //行列Aサイズ printf("行列Aサイズデータ :%s.\n",argments[1]); if((fp=fopen(argments[1],"r"))==NULL){ printf("行列Aサイズデータ読み込み失敗!!"); exit(1); } printf("行列Aサイズ>>"); fscanf(fp,"%d %d",&(matrix_A->size[0]),&(matrix_A->size[1])); printf("%d行%d列.\n",matrix_A->size[0],matrix_A->size[1]); fclose(fp); fp=NULL; matrix_A->data=(double *)malloc(sizeof(double)*matrix_A->size[0]*matrix_A->size[1]); if(matrix_A->data==NULL){ printf("メモリ確保失敗!![matrix_A]\n"); exit(1); } //行列A要素 printf("行列A要素データ :%s.\n",argments[3]); if((fp=fopen(argments[3],"r"))==NULL){ printf("行列A要素データ読み込み失敗!!"); exit(1); } printf("行列A要素>>\n"); for(i=0;i<matrix_A->size[0]*matrix_A->size[1];i++){ fscanf(fp,"%lf",(matrix_A->data+i)); } i=0; for(j=0;j<matrix_A->size[0];j++){ for(k=0;k<matrix_A->size[1];k++){ printf("%5.2lf ",*(matrix_A->data+i)); i++; } printf("\n"); } i=0; fclose(fp); fp=NULL; //行列Bサイズ printf("行列Bサイズデータ :%s.\n",argments[2]); if((fp=fopen(argments[2],"r"))==NULL){ printf("行列Bサイズデータ読み込み失敗!!"); exit(1); } printf("行列Bサイズ>>"); fscanf(fp,"%d %d",&(matrix_B->size[0]),&(matrix_B->size[1])); printf("%d行%d列.\n",matrix_B->size[0],matrix_B->size[1]); fclose(fp); fp=NULL; matrix_B->data=(double *)malloc(sizeof(double)*matrix_B->size[0]*matrix_B->size[1]); if(matrix_B->data==NULL){ printf("メモリ確保失敗!![matrix_B]\n"); exit(1); } //行列B要素 printf("行列B要素データ :%s.\n",argments[4]); if((fp=fopen(argments[4],"r"))==NULL){ printf("行列B要素データ読み込み失敗!!"); exit(1); } printf("行列B要素>>\n"); for(i=0;i<matrix_B->size[0]*matrix_B->size[1];i++){ fscanf(fp,"%lf",(matrix_B->data+i)); } i=0; for(j=0;j<matrix_B->size[0];j++){ for(k=0;k<matrix_B->size[1];k++){ printf("%5.2lf ",*(matrix_B->data+i)); i++; } printf("\n"); } i=0; fclose(fp); fp=NULL; return; } //メイン関数 int main(int argc,char **argv) { FILE *fp=NULL; MATRIX *matrix_A=NULL; MATRIX *matrix_B=NULL; MATRIX *matrix_C=NULL; void input(MATRIX *,MATRIX *,char **); void sum_matrix(MATRIX *,MATRIX *,MATRIX *); matrix_A=(MATRIX *)malloc(1*sizeof(MATRIX)); if(matrix_A==NULL){ printf("[MATRIX]メモリ確保失敗。\n"); exit(1); } matrix_B=(MATRIX *)malloc(1*sizeof(MATRIX)); if(matrix_B==NULL){ printf("[MATRIX]メモリ確保失敗。\n"); exit(1); } matrix_C=(MATRIX *)malloc(1*sizeof(MATRIX)); if(matrix_C==NULL){ printf("[MATRIX]メモリ確保失敗。\n"); exit(1); } input(matrix_A,matrix_B,argv); sum_matrix(matrix_A,matrix_B,matrix_C); free(matrix_A->data); matrix_A->data=NULL; free(matrix_B->data); matrix_B->data=NULL; free(matrix_C->data); matrix_C->data=NULL; free(matrix_A); matrix_A=NULL; free(matrix_B); matrix_B=NULL; free(matrix_C); matrix_C=NULL; printf("終了!\n\n"); return 0; }

その他の回答 (1)

回答No.2

>失礼極まりない質問の仕方をしてしまいしました。申し訳ございません。 こちらこそ、きつく書きましたが丸ごとソースを書いてはプログラムをするうえでは身にならないとの個人的な考え方です。 中には質問に対してすべてソースを記載する回答者もいますが、それに味をしめて「回答されたソースをわからないまま」使用して、追加変更などで深みにはまる方もいるようですので、 そういった意味からも質問者さんが本当にわからない個所をまず絞るということが回答するうえで重要だと思っているだけですから。 >しかしこれをただデバッグすると、行列のサイズがNULLになります。 この「NULLになる」というのはどの部分でしょうか? プログラム自体はコマンドラインから「実行ファイル 読み込むファイル 行列Bサイズデータ 行列A要素データ」と指定する必要がありますが、 読み込むファイルで 1行目:行列Aの行、行列Aの列 2行目:行列Aの要素  ・  ・ n行目:行列Bの行、行列Bの列 n+1行目:行列Aの要素  ・  ・ と定義されている必要があります。 この「実行方法」と「ファイルの内容」 については問題はありませんか? ---------------- 上記とは別に質問についてのヒントのみ記載しておきます。 ・ファイル名の入力について 文字入力には、scanf()、getchar()、gets()等の関数を使用します。 ここで入力したものを読み込むファイル名とします。 ・ファイルからの読み込みについて、  手順は「ファイルオープン→読み書き→ファイルクローズ」となります。 オープン/クローズについては参考のソースにのっているので割愛します。 ファイルフォーマットは、CSV形式なら、 Aの行数、Aの列数 Aの要素 Bの行数、Bの列数 Bの要素 という形式がいいのではないでしょうか。 例えば、A=2x2、B=3x3なら ------------- 2,2 ←Aの行/列数 21,20 20,21 3,2 ←Bの行/列数 11,12,13 14,15,16 17,18,19 ------------- となります。 データを読む場合は、fscanf()で読み込みます。 この時注意しないといけないのは、「読む込むデータ量が可変」であるということです。 その為、参考のソースでも行っていますが、行列の要素数を読み込んだら、そこからデータ入力に必要なメモリを取得します(mallocの部分です)。 後は、読み込んだデータを使用して計算を行っていきます。 いきなり上記全部を行うのは難しいので、一つずつ解決していくのがいいでしょう。

関連するQ&A