• ベストアンサー

csvファイルのデータを構造体に

csvファイルのカンマを数えて任意の文字列を抜き出すまでは出来たのですがそこから構造体に格納するまでがこちらのサイトでも検索しましたがよくわかりません。 ご指摘のほどよろしくお願いします。 csvデータ 番号,名前,住所,電話,年齢,性別 1,佐藤,東京,1234,33,A 2,田中,,5678,22, 3,坂井,名古屋,,,B ・ ・ 番号,住所,電話,年齢を格納する場合 struct k_data { char no[4];/* 出来れば番号を右詰めにしたい */ char add[20]; int tel; int age; } kaiin[256]; /* 文字列を抜き出す↓ */ int main(void) { FILE *fp1,*fp2; char dat[256]; char *ch; int cnt; /* fp1 ファイルオープン */ /* fp2 ファイルクローズ */ while (fgets(dat, 256, fp1) != NULL) { cnt = 0; for (ch = dat; *ch != '\0'; ch++) { if (*ch ==',') { if (cnt == 0) { putc(*ch, fp2); } if (cnt == 2) { putc(*ch, fp2); } if (cnt == 3) { putc(*ch, fp2); } if (cnt == 4) { putc('\n', fp2); } cnt++; } else { if (cnt == 0) { putc(*ch, fp2); } if (cnt == 2) { putc(*ch, fp2); } if (cnt == 3) { putc(*ch, fp2); } if (cnt == 4) { putc(*ch, fp2); } } } putc('\0', fp2); } fclose(fp2); fclose(fp1); }

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

  • ベストアンサー
  • tanma3
  • ベストアンサー率58% (14/24)
回答No.1

まず、取得データをファイルに書き込むのではなく、内部に格納バッファを用意してそこに一時バッファとして格納してください。 CSV仕様上、改行('\n')が要素の終端を表しますので、まず、CSVファイルから1行づつバッファに読み込み、そのバッファデータからカンマ検索実施の上各構造体メンバにセットすればよいと思います。

その他の回答 (2)

回答No.3

 fclose 忘れてた。

回答No.2

#include <stdio.h> #include <stdlib.h> struct k_data{ char no[4]; char add[20]; int tel; int age; }; int main(void) { FILE *fp = fopen("data.txt", "r"); struct k_data kaiin[256]; char tels[16], ages[16]; int i; if(!fp) return 1; for(i = 0; i < 256 ; i ++){ kaiin[i].no[0] = kaiin[i].add[0] = tels[0] = ages[0] = '\0'; if(fscanf(fp, "%[^,]%*c%*[^,]%*c%[^,]%*c%[^,]%*c%[^,]%*c%*[^\n] ", kaiin[i].no, kaiin[i].add, tels, ages) == EOF) break; kaiin[i].tel = strtol(tels, NULL, 10); kaiin[i].age = strtol(ages, NULL, 10); printf("(%4s)(%20s)(%8d)(%8d)\n", kaiin[i].no, kaiin[i].add, kaiin[i].tel, kaiin[i].age); } return 0; }

関連するQ&A

  • fgetsを使ってcsvからcsvに

    csvファイルからfgetsを使い任意の文字列を取り出して新たなcsvファイルに出力したいのですがなかなかうまくいきません。ご指摘の方よろしくお願いします。 csvデータ 社名,住所,番号,設立年,従業員数,分類 山川商事,東京,123,8,60,証券 谷運輸,,578,20,400,運送 空海コンピュータ,,456,,300,ソフトウェア          ・          ・          ・ データの3,5,6番目を取り出したい。(データが入ってない箇所もある) #include <stdio.h> int main(void) { FILE *fp1,*fp2; char data[256]; char *data_p = data; int cnt = 0; char ch[256]; char *ch_p = ch; //ファイルオープン(fp1)// //ファイルクローズ(fp2)// while (fgets(data, 255, fp1) != NULL) { if (*data_p != ',') { if(cnt == 2) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 4) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 5) { *ch_p = *data_p; data_p++; ch_p++; } } else { if (cnt == 2) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 4) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 5) { *ch_p = *data_p; data_p++; ch_p++; } cnt++; x++; } } y = '\0'; fprintf(fp2, "%s", ch); fclose(fp1); fclose(fp2); }

  • csvファイルを構造体に読み込みたい

    C言語初心者です。 csvファイルのデータを1行ずつ構造体に読み込みたいのですが、うまくできません。 #define MAX_SIZE 100 char filename[] = ″test.csv"; struct ALL_DATA{ int cnt; char list[10]; char addr[10]; char cmd[10]; char csize[10]; char input[10]; char icmd[10]; char input2[10]; }; for (int lp = 0; lp < 10; lp++){ FILE *fp; struct ALL_DATA ADATA[MAX_SIZE]; // 構造体配列の宣言 if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%d,%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],\n", &ADATA[fc].cnt, ADATA[fc].list, ADATA[fc].addr,ADATA[fc].cmd,ADATA[fc].csize,ADATA[fc].input,ADATA[fc].icmd,ADATA[fc].input2); } } fclose(fp); while (i < MAX_SIZE){ printf("ADATA[i].cnt -> %d, ADATA[i].list -> %s, ADATA[i].addr -> %s, ADATA[i].cmd -> %s, ADATA[i].csize -> %s, ADATA[i].input -> %s, ADATA[i].icmd -> %s, ADATA[i].input2 -> %s\n",ADATA[fc].cnt, ADATA[fc].list,ADATA[fc].addr,ADATA[fc].cmd,ADATA[fc].csize,ADATA[fc].input,ADATA[fc].icmd,ADATA[fc].input2); i++; } } 読み込みたいcsvデータは 1 test 0x0012 write 0x001 yes 0xabc yes 2 testa 0x00cd read 0x024 0x1a3 のように、「数字、文字列・・・」と並んでいます。 このデータを取り込んで表示させたところ、 最初の数字は問題ないのですが、ADATA[i].addr から値がおかしくなり、 ADATA[i].addr = 0x0012write ADATA[i].cmd = write ADATA[fc].csize = 0x001yes のように、16進数を文字列として構造体に入れるときに、次の文字(英字)まで一緒に含んでしまう現象が出ております。 ネットで調べて、csvファイルから構造体に取り込む方法はいくつか見たのですが、同じようにしている(と思っている)のにうまくいかないため、質問させていただきました。 原因がわかる方がいらっしゃいましたら、アドバイスをよろしくお願いいたします。

  • 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 . . . . . ***********************************************

  • ファイル読込時に構造体の文字列ポインタに割当てたいと

    ファイル読込時に構造体の文字列ポインタに割当てたいと思っています。 (new 演算子を使用します。) 文字列の長さが不定です。 どうすれば、文字列の長さを知ることができますか? 以下のようなところまでは作れましたが、 困っています。 void loaddata()のfscanf関数の部分です。 ほかにも関数の void outputdata() void deletedata() がありますが、長いので省略しました。 ********************************************************** #include<stdio.h> #include<string.h> class data { public: struct basic { char *name; int age; struct basic *next; }; private: struct basic *base; struct basic *base_top; int cnt; public: data::data() { cnt=0; } void inputdata(char *name,int age) { if(cnt==0) { base=new basic; base_top=base; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } else { base->next=new basic; base=base->next; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } } void savedata() { base=base_top; FILE *fp; fp=fopen("dat.txt","w"); for(int i=0;i<cnt;i++) { fprintf(fp,"%s\t%d\n",base->name,base->age); base=base->next; } fclose(fp); } void loaddata() { if(cnt!=0){deletedata();} cnt=0; FILE *fp; fp=fopen("dat.txt","r"); while(1) { fscanf(fp,"%s\t%d\n",base->name,base->age); } } };

  • CSVファイルの内容を構造体に格納したい(Unix使用)。

    こんにちは。私は30代の男性です。 「名前」「身長」「体重」が記載されたCSVファイルの内容を読み取って、構造体の「name」「height」「weight」に格納するプログラムを作っています。CSVの内容は A,175,80 B,167,89 C,155,45 ・ ・ ・ Z,188,70 だと仮定します。数値が読み取れているか、下記のように「tp = strtok(file_image, ",\n" );」の前後に「printf("%s\n", file_image);」を置いてみたら、strtok前では全て表示されるのに、strtok後では「ABC」しか表示されません。これでは全てのデータを構造体に格納できないので、困っています。 1.どのようにすれば、数字も取り出せる(読み取れる)でしょうか? 2.効率よく構造体に格納するには、どのようにしたらよいでしょうか? アドバイスを頂ければ幸いです。宜しくお願いいたします。 #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fp = NULL; int rtn = 0; if ((fp = fopen(argv[1], "r")) == NULL) { printf("ファイルオープンに失敗しました。\n"); return 1; } if (argc != 2) { printf("ERROR: オプションの数に過不足があります。\n"); return 1; } rtn = change_csv(fp); return 0; } int change_csv(FILE *fp) { int i; int j; char file_image[256]; /* 読み込んだ先のメモリの領域 */ char *tp; for (i = 0; i <= 256; i++) { if (fgets(file_image, 256, fp) == NULL) { if (ferror(fp) != 0) { printf("ERROR: 読み込みに失敗しました。\n"); return 1; } } if (feof(fp) != 0) { break; } printf("%s\n", file_image); tp = strtok(file_image, ",\n" ); printf("%s\n", file_image); } fclose(fp); return 0; }

  • VC++のfopenのファイル名の指定方法について

    下記のようなcsvファイルを間引くプログラムを改変したいと思っています。 環境はVS2008 C++ コンソールアプリケーションです。 #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { FILE *fp,*fp1; int i, j, retu, ch, cnt=0; char data[100]; char a=0; fp=fopen("data.csv","r"); fp1=fopen("kekka.csv","w"); cnt=0; retu=0; while (1){ ch=fgetc(fp); if (ch=='\n') break; } while((ch=fgetc(fp))!=EOF){ data[retu]=ch; retu++; if (ch=='\n'){ cnt++; if (cnt>=10){ cnt=0; for(i=0;i<retu;i++){ printf("%c",data[i]); fputc(data[i], fp1); } } retu=0; } } return 0; } ただ毎回csvファイルの名前をdata.csvに書き換え、さらにkekka.csvを別名にして保存しなければいけないためとても手間です。 そこでその部分を実行時にscanfなどを用いて変更したいと思ったのですがうまくいきません。 fopenでファイル名を実行時(ビルド時)に変更するにはどうすればよいのでしょうか。 ご教授お願いします。

  • csvファイルの実績データをC言語で解析するのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 1レコード目がカラム名なので2レコード目から足し合わせるんですがそこのところもよくわからずじまいで... 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

  • 1000000レコードもあるcsvファイルの実績データをC言語で計算しているのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

  • csvファイルを構造体に格納したいです

    ファイル内容 ******************** あいう,,さしす たちつ,なにぬ,はひふ まみむ,, あいう,win, ******************** #include <stdio.h> #include <string.h> #define MBF 256 struct tb{ char aaa[32]; char bbb[32]; char ccc[32]; }; int main(){ struct tb tbl[20]; struct tb *tp; int ntb,itb; FILE* fi; FILE* fo; char buff[MBF]; // 入力 fi = fopen("sample.csv","r"); // 検査省略 if( fi == NULL ){ printf( "%sファイルが開けません\n" ); return -1; } ntb = 0; while ( fgets(buff,MBF,fi ) != NULL ) { strcpy(tbl[ntb].aaa,strtok(buff,",")); strcpy(tbl[ntb].bbb,strtok(NULL,",")); strcpy(tbl[ntb].ccc,strtok(NULL,",")); ntb++; } fclose( fi ); // 出力 fo = fopen("csvo.csv","w"); if( fo == NULL ){ printf( "%sファイルが開けません\n" ); return -1; } for ( itb=0;itb<ntb;itb++ ) { tp = tbl+itb; fprintf(fo,"%s%s%s",tp->aaa,tp->bbb,tp->ccc); } fclose( fo ); return 0; } csvファイルないようが以下であれば格納できるけど、すごく困ってます。 ******************** あいう,かきく,さしす たちつ,なにぬ,はひふ まみむ,やゆよ,らりる ********************

  • csvファイルを構造体に格納したいです

    ファイル内容 ******************** あいう,,さしす たちつ,なにぬ,はひふ まみむ,, あいう,win, ******************** #include <stdio.h> #include <string.h> #define MBF 256 struct tb{ char aaa[32]; char bbb[32]; char ccc[32]; }; int main(){ struct tb tbl[20]; struct tb *tp; int ntb,itb; FILE* fi; FILE* fo; char buff[MBF]; // 入力 fi = fopen("sample.csv","r"); // 検査省略 if( fi == NULL ){ printf( "%sファイルが開けません\n" ); return -1; } ntb = 0; while ( fgets(buff,MBF,fi ) != NULL ) { strcpy(tbl[ntb].aaa,strtok(buff,",")); strcpy(tbl[ntb].bbb,strtok(NULL,",")); strcpy(tbl[ntb].ccc,strtok(NULL,",")); ntb++; } fclose( fi ); // 出力 fo = fopen("csvo.csv","w"); if( fo == NULL ){ printf( "%sファイルが開けません\n" ); return -1; } for ( itb=0;itb<ntb;itb++ ) { tp = tbl+itb; fprintf(fo,"%s%s%s",tp->aaa,tp->bbb,tp->ccc); } fclose( fo ); return 0; } csvファイルないようが以下であれば格納できるけど、すごく困ってます。 ******************** あいう,かきく,さしす たちつ,なにぬ,はひふ まみむ,やゆよ,らりる ********************

専門家に質問してみよう