• 締切済み

256*256の読み込み、fscanfではどうも、、、

256*256の行列データファイルを読み込みたいのですが、 fscanf(file_i,"%lf,%lf,%lf",&d_value1,&d_value2,&d_value3); while(!feof(file_i)){ と256列分書くのは少ししんどいなぁと思いまして質問します。 なにか具体的な方法を教えていただければ幸いです。ちなみに読み込んだデータはd_data[256][256]の中に入れることができたらいいなぁと思っています。 よろしくお願いします。

みんなの回答

  • bulgaris
  • ベストアンサー率50% (8/16)
回答No.6

1つの案として fscanf( file_i, "%lf", &(d_data[i][j])); を256*256回、ループさせる。

すると、全ての回答が全文表示されます。
noname#11920
noname#11920
回答No.5

更にミスを...。 buf[strlen(buf) - 1] = '\0'; /* 改行文字を切り捨て */ は buf[strlen(buf) - 2] = '\0'; です。 しかし、この行は無くても構いません。 (ミスばかりして恥ずかしい...)

すると、全ての回答が全文表示されます。
noname#11920
noname#11920
回答No.4

済みません。ドジをしました。 思いっきりバグを作っていました。 正しくは次の通りです。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* M * N 行列 */ #define M 256 #define N 256 #define BUFFER_SIZE 8192 /* 1 行分のバッファサイズ */ #define TOKEN ", \t" /* データの区切り文字 */ typedef double data_type; /* 配列が double 型の場合 */ int main(void); int read_matrix(const char *file_name, data_type matrix[][N]); data_type string_to_data_type(const char *s); /* 文字列を目的の型に変換 */ int main(void) { data_type matrix[M][N]; read_matrix("data_file.txt", matrix); } int read_matrix(const char *file_name, data_type matrix[][N]) { int i, j; static char buf[BUFFER_SIZE]; char *p, *q; FILE *fp; if ((fp = fopen(file_name, "r")) == NULL) { /* ファイルのオープンに失敗した時は 0 を返す。 */ return 0; } for (i = 0; i < M; ++i) { if (fgets(buf, sizeof(buf), fp) == NULL) { /* 読み込みエラー */ fclose(fp); return 0; } buf[strlen(buf) - 1] = '\0'; /* 改行文字を切り捨て */ p = buf; for (j = 0; j < N; j++) { q = strtok(p, TOKEN); if (q == NULL) { /* データが不正 */ fclose(fp); return 0; } matrix[i][j] = string_to_data_type(q); p = NULL; } } fclose(fp); return 1; } data_type string_to_data_type(const char *s) { return(atof(s)); } C では出来るだけ多次元配列を使わないようにしていたので、初歩的なミスをしてしまいました。 申し訳ありません。

すると、全ての回答が全文表示されます。
noname#11920
noname#11920
回答No.3

ちょっと煩雑なコードですが、一応一般化してあるので、 流用が効くと思います。 コンパイルが通ることは確認しましたが、 正しく動くかは不明です(多分大丈夫でしょう)。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* M * N 行列 */ #define M 256 #define N 256 #define BUFFER_SIZE 8192 /* 1 行分のバッファサイズ */ #define TOKEN ", \t" /* データの区切り文字 */ typedef double data_type; /* 配列が double 型の場合 */ int main(void); int read_matrix(const char *file_name, void **matrix); data_type string_to_data_type(const char *s); /* 文字列を目的の型に変換 */ int main(void) { data_type matrix[M][N]; read_matrix("data_file.txt", (void **)&matrix); } int read_matrix(const char *file_name, void **matrix) { data_type **data = *matrix; int i, j; static char buf[BUFFER_SIZE]; char *p, *q; FILE *fp; if ((fp = fopen(file_name, "r")) == NULL) { /* ファイルのオープンに失敗した時は 0 を返す。 */ return 0; } for (i = 0; i < M; ++i) { if (fgets(buf, sizeof(buf), fp) == NULL) { /* 読み込みエラー */ fclose(fp); return 0; } buf[strlen(buf) - 1] = '\0'; /* 改行文字を切り捨て */ p = buf; for (j = 0; j < N; j++) { q = strtok(p, TOKEN); if (q == NULL) { /* データが不正 */ fclose(fp); return 0; } data[i][j] = string_to_data_type(q); p = NULL; } } fclose(fp); return 1; } data_type string_to_data_type(const char *s) { return(atof(s)); }

すると、全ての回答が全文表示されます。
回答No.2

こんな感じでどうでしょうか。コンパイルチェックはしてないのですが、ま、考え方だけでもどうぞ。 char line[8192]; double d_data[256][256]; for (size_t x=0;fgets(line,8192,file_i)!= NULL;x++) { char* reading = line; for (size_t i=0; i< 256; i++) { fscanf(reading,"%lf,",&d_value[x][i]); while (*reading > '0' && *reading < '9') { reading++; } if (*reading == ',') { reading++; } } }

すると、全ての回答が全文表示されます。
  • goo-tara
  • ベストアンサー率24% (10/41)
回答No.1

挙げられている例では、データファイルの中身が適切であるかを確認していませんね。 freadを使って、1文字づつ読み込んだ文字の妥当性や、行あたりのデータ数などを確認しながら、配列変数に代入していくべきだと考えます。 問題を見つけたときは、データファイルの何行目、何文字目に、どのような不適合があったか記録を残して、処理を中断しましょう。 以下、参考URLより抜粋 『scanf()で読み込み不一致が起こる問題では、上記 「atoi()、atol()、atof()」を使って回避します。 読み込み不一致は、scanf()を for や while などのループの中で用いた場合、入力バッファに残されたデータを永遠に受け付けないため無限ループになってしまい意外に深刻な問題となります。 そのためデータを一旦、scanf("%s", ○)や gets()を用いて文字列として入力し、それから上記の変換関数を用いて期待するデータ型に変換するのです。』 今回の場合、標準入力でなくファイル読み込みであるため、もう少し工夫が必要ですね。

参考URL:
http://www9.plala.or.jp/sgwr-t/c/sec07.html#s7-4
すると、全ての回答が全文表示されます。

関連するQ&A