CSVファイルの読み込み方法とデータ構造体への格納方法

このQ&Aのポイント
  • fscanf関数を使ってCSVファイルの内容をデータ構造体に格納する方法を教えてください。
  • 質問者は4列目以降のデータがうまく読み込めていないと報告しています。
  • 初歩的な質問ですが、回答をお願いします。
回答を見る
  • ベストアンサー

csvファイルの読み込み

fscanf関数を用いて、csvファイルの内容を構造体のそれぞれのメンバに読み込んで表示させようとしているのですが、4列目以降が上手く読み込めません。初歩的な質問で申し訳ありませんがどなたか教えてください。 ****************************ソース************************************************ #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME "view_001_McdlData.csv" #define FILE_SIZE 819200 struct Data{ int DataNo; int FrameNo; int SampleNo; char Digital; double voltage; double trigger; double C; double D; }; int main(int argc, char *argv[]) { FILE* fp,*fo, *fi; // ファイルポインタ用 int n, i, file_size; double time,vel[FILE_SIZE]; struct Data *dat; char buff[SIZE]; if ((fp = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; //データの読み込み while((fscanf(fp, "%d,%d,%d,%s,%lf,%lf,%lf,%lf",&dat[i].DataNo,&dat[i].FrameNo,&dat[i].SampleNo,&dat[i].Digital,&dat[i].voltage,&dat[i].trigger,&dat[i].C,&dat[i].D)) !=EOF ){ printf("%d %d %d %s %lf %lf %lf %lf\n",dat[i].DataNo,dat[i].FrameNo,dat[i].SampleNo,dat[i].Digital,dat[i].voltage,dat[i].trigger,dat[i].C,dat[i].D); i++; } fclose(fp); return 0; } ***********************************csvファイルの内容************************************ 0,1,0,0x3F,2.270000,0.000000,-1.000000,-1.000000 1,1,1,0x3F,2.260000,0.010000,-1.000000,-1.000000 2,1,2,0x3F,2.260000,0.010000,-1.000000,-1.000000 3,1,3,0x3F,2.260000,0.010000,-1.000000,-1.000000 4,1,4,0x3F,2.260000,0.010000,-1.000000,-1.000000 5,1,5,0x3F,2.260000,0.000000,-1.000000,-1.000000 ***************************************************************************************************

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

  • ベストアンサー
  • Quant
  • ベストアンサー率18% (23/122)
回答No.2

何をやりたいのかわからないが、こういうこと? #include <stdio.h> #include <string.h> #include <stdlib.h> #define FILE_NAME "view_001_McdlData.csv" struct Data{ int DataNo; int FrameNo; int SampleNo; char Digital; double voltage; double trigger; double C; double D; }; main() { FILE *fp; int n,i; struct Data *dat; if ((fp = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } //データの読み込み n = -1; dat = NULL; do { n++; dat = realloc(dat,sizeof(struct Data) * (n + 1)); } while(fscanf(fp, "%d,%d,%d,%x,%lf,%lf,%lf,%lf", &dat[n].DataNo,&dat[n].FrameNo,&dat[n].SampleNo,&dat[n].Digital, &dat[n].voltage,&dat[n].trigger,&dat[n].C,&dat[n].D) != EOF); fclose(fp); for(i = 0;i < n;i++) printf("%d %d %d %c %lf %lf %lf %lf\n", dat[i].DataNo,dat[i].FrameNo,dat[i].SampleNo,dat[i].Digital, dat[i].voltage,dat[i].trigger,dat[i].C,dat[i].D); }

その他の回答 (2)

回答No.3

 dataの配列の領域を確保するのにfile_sizeを使うのはおかしいし、 ファイルをテキストで開いた場合、ftellが返すのは "ファイルポインタの位置を示す何らかの数値"であって、 文字数やバイト数とは限らない。

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

4列目って文字型だよね%sだから。 文字型のfscanfの%sには&dat[i].Digitaじゃなくdat[i].Digitalでは。 しかも文字列だから最低char Digital[2];じゃないと文字列+'\0'が格納できないでしょ。 一文字なら%c

関連するQ&A

  • datファイルの読み込み

    初歩的な質問ですみません。 今、819200行のファイルをfscanfで読み込んで配列に格納しているのですが、実行してみるとBus errorが出力されてしまい、うまく格納できません。どなたか至急教えてもらえませんか? ***************************ソース************************************************************ #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #define pi 3.1415926535 //円周率 #define FILE_SIZE 819200 #define FILE_NAME "test.dat" struct Data{ int time; double voltage; double velocity; double pressure; double trigger; }; int main() { int k,n,N,i=0,j; struct Data dat[FILE_SIZE]; FILE *fp1; FILE *fp2; if ((fp1 = fopen(FILE_NAME,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } //データの読み込み while((fscanf(fp1, "%d %lf %lf %lf %lf",dat[i].time,dat[i].voltage,dat[i].velocity,dat[i].pressure,dat[i].trigger)) !=EOF ){ i++; } fclose(fp1); return 0; } ***************************************************************************************** ********************test.datファイル********************************************** -2.64316 2.329595 0.697657 0.001373 -4.861982 -2.64314 2.325628 0.671961 0.001984 -4.744793 -2.64312 2.320745 0.640333 0.001678 -4.659953 -2.64310 2.319829 0.634400 0.002289 -4.707866 -2.64308 2.319219 0.630449 0.002289 -4.699321 -2.64306 2.317082 0.616607 0.002594 -4.532387 . . . . . *********************************************************************************** 環境はmac osです。 よろしくおねがい致します。

  • 容量の大きいCSVファイルの読み込みについて

    容量の大きいCSVファイルの読み込みについて 23メガバイトあるCSVファイルに格納し、datファイルに書き込みを行いたいのですが、実行してみるとセグメンテーション違反が表示され上手くいきません。どなたか具体的に教えてください。 環境はMacOSです。 下にファイルを格納し標準出力するまでのプログラムとCSVファイルの内容を記述します。 //********************************************************************************// #include <stdio.h> #include <string.h> #include <stdlib.h> #define D_LENGTH 10000000000000 struct Data{ double voltage; double pressure; double trigger; }; int main(int argc, char *argv[]) { FILE* fp; // ファイルポインタ用 double ret; int n, i = 0; struct Data *dt; fp = fopen("p37-e1.csv","r"); if (fp == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } dt = (struct Data*)malloc(sizeof(struct Data)*D_LENGTH); while( ( ret = fscanf( fp, "%[^,],%[^,],%[^,],%lf",dt[i].voltage,dt[i].pressure,dt[i].trigger) ) != EOF ){ i++; } printf("\n"); printf("Read File*******************\n"); for (n = 0; n < i; n++) printf("%lf,%lf,%lf\n",dt[n].voltage,dt[n].pressure,dt[n].trigger); free(dt); return(0); } //***************************************************************************// p37-e1.csv //***************************************************************************// 2.329595,0.001373,-4.861982 2.325628,0.001984,-4.744793 2.320745,0.001678,-4.659953 2.319829,0.002289,-4.707866 2.319219,0.002289,-4.699321 2.317082,0.002594,-4.532387 2.312505,0.001984,-4.575723 . . . . //*********************************************//

  • CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後

    CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。 プログラム ************************************************** #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME_00 "f_00_01.CSV" struct Data{ double value; double ave; }; int main(int argc, char *argv[]) { FILE* fp,*fo; // ファイルポインタ用 int n, i, file_size; struct Data *dat; if ((fp = fopen(FILE_NAME_00,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; for(i=0;i<file_size;i++){ fscanf(fp,"%lf",&dat[i].value); printf("%lf\n",dat[i].value); i++; } fclose(fp); printf("\n"); free(dat); return 0; } *************************************************** f_00_01.CSV *************************************************** 2.313725 2.312810 2.314031 2.316167 2.315557 2.313725 . . . . . ***********************************************

  • ファイル入力のエラー

    以下のファイルを配列に読み込むプログラムを作っています。 1987 1100 12 23 2.467164 0.75153 1989 1202 12 31 2.456249 0.72896 1990 1204 9 28 2.484802 0.763903 1991 1206 11 26 2.520005 0.750182 1985 1207 9 26 2.499319 0.749116 以下の通りプログラムを組んでみました。 コンパイルしたところ、出力はされませんでした。 エラーも出ていないので、入力、出力などどこが悪いのかわかりません。 ほとんど初心者です。間違いが分かる方、よろしくお願いします。 #include<stdio.h> #define SIZE 5 main() { int a, b, c, d, i; static int year[SIZE],month[SIZE],day[SIZE],code[SIZE];   double e, f; static double latitude[SIZE],longitude[SIZE]; FILE *fp; fp=fopen("c\distance.dat","r"); while((fscanf(fp,"%d%d%d%d%lf%lf",&a,&b,&c,&d,&e,&f)) !=EOF) { year[i]=a; month[i]=b; day[i]=c; code[i]=d; latitude[i]=e; longitude[i]=f; i++; printf("%13d%8d%8d%8d%9.6lf%9.6lf\n",&a,&b,&c,&d,&e,&f); } fclose(fp); return(0); }

  • C言語でファイルから複素数の値を読み込んで表示させるプログラムを作って

    C言語でファイルから複素数の値を読み込んで表示させるプログラムを作っています。 扱う値が実数のみの場合に関しては問題ないのですが、 複素数を読み込む時には、実数のみの場合や、虚数のみの場合もあり、 どう読み込んでいいか分からず、アドバイスを戴きたいと考えております。 それ以外のデータの取り扱い自体は問題ないと思います。 下は実数の値を読み込むプログラムとデータセット、 それを拡張した複素数の値を読み込むプログラムとデータセットになっております。 アドバイス、よろしくお願いいたします。 -------------------------------------------------------------------------------- /*データセット sample.dat*/ 4 3.5 -2 9 12 37.8 65.4 0.4 79.5 3 23.4 5.3 -------------------------------------------------------------------------------- /*プログラム本体 read.c*/ #include <stdio.h> #include <stdlib.h> #define LOW 3 #define COLUMN 4 int main(void){ int i,j; double x[LOW][COLUMN]; if((fp = fopen("sample.dat","r"))==NULL){ printf("The file is not found. : sample.dat \n"); exit(1); } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ fscanf(fp,"%lf",&x[i][j]); } } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ printf("%lf\n",x[i][j]); } } return 0; } -------------------------------------------------------------------------------- /*データセット sample_C.dat*/ 4+i i -2 9+i 12 37.8-i 65.4i 0.4+i 79.5 3+i 23.4 5.3 -------------------------------------------------------------------------------- /*プログラム本体 read_C.c*/ #include <stdio.h> #include <stdlib.h> #define LOW 3 #define COLUMN 4 typedef struct{ double re; double im; }C_double; int main(void){ int i,j; C_double x[LOW][COLUMN]; if((fp = fopen("sample_C.dat","r"))==NULL){ printf("The file is not found. : sample_C.dat \n"); exit(1); } /*改良したい読み込み部分*/ for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ fscanf(fp,"%lf",&x[i][j].re); fscanf(fp,"%lf",&x[i][j].im); } } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ if(x[i][j].re!=0){ if(x[i][j].im!=0){ printf("x[%d][%d]=%lf+%lfi\n",i,j,x[i][j].re,x[i][j].im); } else{ printf("x[%d][%d]=%lf\n",i,j,x[i][j].re); } } else{ if(x[i][j].im!=0){ printf("x[%d][%d]=%lfi\n",i,j,x[i][j].im); } else{ printf("x[%d][%d]=0\n",i,j); } } } } return 0; }

  • CSVファイルの読み込み

    以下のようなCSVファイルを読み込みたいと思っています。 0.575092,0.030525 0.565324,0.018315 0.555556,0.013431 0.553114,0.013431 0.54823,0.015873 0.538462,0.013431 0.531136,0.006105 0.52381,-0.003663 0.516484,-0.010989 0.501832,-0.015873 0.489622,-0.018315 0.477412,-0.020757 0.46276,-0.020757 ・ ・ ・ 50000*2のデータで、以下のようなプログラムを使用しました。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 50000 #define M 2 /* データの区切り文字 */ #define SEP_DATA ',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン */ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し */ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換 */ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す */ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す */ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ */ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保 */ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化 */ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み */ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力 */ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } しかし、コンパイルは通るのですが実行時にエラーが出てしまいます。 データの大きさに問題があると思うのですが、原因がわかりません。おかしな所のご指摘を頂きたいです。よろしくお願いします。

  • 離散フーリエ変換(DFT)のプログラム

    タイトルの通りのレポートを出されたのですが、その問題に似たサンプルソースすら何をいっているのかわからない状態です。ひとまず、サンプルソースが何をいっているのか理解したいので、いくつか教えてください。 ソースです。質問はその後に書かせてもらいました。 #include<stdio.h> #include<math.h> #define N 10 #define F 0.1 #define PI 3.14151692 #define SQR(x) ((x)*(x)) void func() { int n; FILE *fp; fp=fopen("temporal.data","w"); for(n=0;n<N;n++) fprintf(fp,"%lf\n",cos(2.0*PI*F*(double)n)); fclose(fp); } void get_data(double x[]) { int n; FILE *fp; fp=fopen("temporal.data","r"); for(n=0;n<N;n++) fscanf(fp,"%lf",&x[n]); fclose(fp); } void dft(double x[],double X_r[],double X_i[]) { int k,n; for(k=0;k<N;k++){ X_r[k]=X_i[k]=0.0; for(n=0;n<N;n++){ X_r[k]+=x[n]*cos(2.0*PI*(double)n*(double)k/(double)N); X_i[k]-=x[n]*sin(2.0*PI*(double)n*(double)k/(double)N); } } for(k=0;k<N;k++) printf("X[%d]=%lf+j%lf\n",k,X_r[k],X_i[k]); } void amplitude(double X_r[],double X_i[]) { int k; FILE *fp; double amp; fp=fopen("amp.data","w"); for(k=0;k<N;k++){ amp=sqrt(SQR(X_r[k])+SQR(X_i[k])); fprintf(fp,"%lf\n",amp); } fclose(fp); } main() { double x[N],X_r[N],X_i[N]; func(); get_data(x); dft(x,X_r,X_i); amplitude(X_r,X_i); } 文字数の制限があるみたいなので、質問を別にさせてもらいます。

  • C言語による構造体の値渡しについて

    以下プログラムを作成しました。 1.read_file関数によりファイルを読み込み。 2.avg_kokugo関数により、国語の平均点を出す。 という流れで組まれているのですが、 1.read_file関数実行時に、dat構造体を渡しています。 2.read_file関数内で、fscanfによる読み込みを行い、dat[i].name,&dat[i].kokugo,&dat[i].sansuに格納しているみたいに感じます。 ここで、疑問なのが、 「構造体を値渡しでdatをread_file関数に渡してる」と思っているのですが、 「read_file関数から、値渡しで渡された構造体datに、値を格納することはできるのでしょうか?」 本を参考にして勉強していたのですが、 「構造体は、値渡しの時に読み込みはできるが、更新はできない」 と書かれていたのです。(ポインタ参照渡しの時は可能。) なぜ今回、read_file関数から、構造体datに値の格納ができるのでしょうか? 更新と新規格納は意味が異なるからなのでしょうか? ご教授よろしくお願いします。 <ソース> #include <stdio.h> //グローバル #define FNAME "test.txt" struct score{ char name[20]; int kokugo; int sansu; }; int read_file(struct score dat[],int n); float avg_kokugo(struct score dat[],int n); int main(void){ struct score dat[3]; int ret; float kokugo; float sansu; ret= read_file(dat,3); if(ret <0){ return 0; } kokugo = avg_kokugo(dat,3); printf("国語の平均 %.1f\n",kokugo); return 0; } int read_file(struct score dat[],int n){ FILE *fp; //ファイルポインタ int i; fp=fopen(FNAME,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return -1; //-1によるプログラム強制終了 } //データ読み込み i=0; //datに保存していく。 while((fscanf(fp,"%s%d%d",dat[i].name,&dat[i].kokugo,&dat[i].sansu)) != EOF){ i=i+1; //ファイル件数読み込み } fclose(fp); return 0; } float avg_kokugo(struct score dat[],int n){ int sum; //合計 float answer; int i; sum=0; for(i=0;i<n;i++){ sum = sum + dat[i].kokugo; } //平均点を求める answer =(float)sum / (float)n; return answer; }

  • C言語 ファイルの読み込みについて

    以下のようなプログラムを実行します \nで改行が行われません。なぜでしょうか? #include <stdio.h> void main () { FILE *fp; double a, b; int count=0; fp = fopen("arm_x.csv","r"); while(1) { fscanf(fp,"%lf%lf\n",&a,&b); printf("%f::%f\n",a,b); count++; if(count==10)break; } fclose(fp); } csvファイルは 0.0 0.1 0.2 0.3 0.4 0.5 0.1 0.2 0.3 0.4 0.5・・・ 0.2 0.3 0.4・・・・・・・・・ : : です。 実行結果はこのようになってしまいます。 0.0 0.1 0.2 0.3 0.4 0.5 : :

  • ファイルの読み込みが上手くいかず困っています。

    #include<stdio.h> #include<math.h> #include<time.h> #define i0 2 /*流体部分の最小格子番号*/ #define j0 2 #define k0 2 #define in 41 /*流体部分の最大格子番号*/ #define jn 41 #define kn 41 #define imax 44 /*境界を含めた格子の数*/ #define jmax 44 #define kmax 44 #define N 100000 void sabun(void); int i,j,k,n,pgosa,vgosa,x,y,z; double u[imax][jmax][kmax], v[imax][jmax][kmax], w[imax][jmax][kmax], p[imax][jmax][kmax]; double u2[imax][jmax][kmax], v2[imax][jmax][kmax], w2[imax][jmax][kmax], p2[imax][jmax][kmax]; double Vn=-1.0, a=10.0; /*初期値*/ double dt=0.001, dx=0.025, dy=0.025, dz=0.025, rei=250000.0; double dx2, dy2, dz2, po; main() { FILE *fpin,*fpout; clock_t start,end; start = clock(); /*時間計測開始*/ fpin=fopen("H-clock.dat", "r"); /*入力ファイル*/ if(fpin==NULL) { printf("入力ファイルのオープンに失敗しました"); return 0; } x=i-1; y=j-1; z=k-1; for(i=i0;i<=in+1;i++){ for(j=j0;j<jn+1;j++){ for(k=k0;k<kn+1;k++){ fscanf(fpin,"%d %d %d %.6lf %.6lf %.6lf %.6lf\n",&x,&y,&z,&u[i][j][k],&v[i][j][k],&w[i][j][k],&p[i][j][k]); printf("%d %d %d %.6lf %.6lf %.6lf %.6lf\n",x,y,z,u[i][j][k],v[i][j][k],w[i][j][k],p[i][j][k]); } } } 読み込みの部分のある部分まで載せているのですが読み込みの部分に問題が あると思うのですがどうすれば読み込んでくれるのか分かりません。ですので解決法を教えていただけると助かります、よろしくお願いします。