• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:test.csvの内容)

test.csvの内容を表示するプログラム

このQ&Aのポイント
  • test.csvの内容を表示するプログラムを作成しましたが、コンパイル後実行するとエラーが発生します。
  • プログラムはファイルから1行ずつ読み込み、カンマで区切られた各項目を構造体に保存して表示します。
  • エラーの原因は、ファイルポインタが初期化されていないことです。fpの初期化を行うことで問題を解決できます。

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

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

#5です。質問を良く読んでいませんでした(申し訳ない)。 >真ん中のq,r,s,t以降の内容を表示させたく、・・・ とのことですので、whileは省略してはならず。質問のプログラムを用いることになります。失礼しました。  せっかくですので、やっていることの説明を付けておきます。 /* これは回答プログラムです */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME "test.csv" #define SIZE 32 #define ALL 6 struct tb{ char a[SIZE]; char b[SIZE]; char c[SIZE]; char d[SIZE]; }; struct set2 { char word[4]; //設定文字(列) long offset; //file position }; int main(int argc, char *argv[]) { struct tb test; FILE *fp; char buff[SIZE]; long pos; int i; char *search; //検索文字 struct set2 table[ALL]= { //abcのみで失礼 "b",0, "f",8, "j",16, "n",24, "r",32, "v",40 }; if(argc!=2) return 1; search=argv[1]; fp=fopen(NAME,"r"); //data table からオフセット値を得る for(i = 0; i < ALL; i++) //もし、data table の検索文字(word)があれば脱 if(strstr(search, table[i].word) != NULL) break; //ただし、該当文字がなければエラー if(i >= ALL){ fclose(fp); return -1; } //file position は data table 番号i にある offset値をセット pos = table[i].offset; //ヘッドを指定 file position まで移動する fseek(fp,pos,SEEK_SET); while(fgets(buff,SIZE,fp) != NULL){ //各項目の設定 strcpy(test.a,strtok(buff,",\"")); strcpy(test.b,strtok(NULL,",\"")); strcpy(test.c,strtok(NULL,",\"")); strcpy(test.d,strtok(NULL,",\"")); fclose(fp); printf("%s %s %s %s \n",test.a,test.b,test.c,test.d); } fclose(fp); return 0; } /* これは上とは違う別物の参考プログラムです */ #include <stdio.h> #include <string.h> #define SIZE 128 #define ALL 10 int main(void) { char buff[SIZE]; int seek_point, i = 0; FILE *fp; char *key, *pref[] = {"b","f","j","n","r","v","い","き","し","ち"}; fp = fopen("test.csv", "r"); //最初の検索文字をセット key = pref[i]; //現在の file position をセット seek_point = ftell(fp); //file を1行読み込む while(fgets(buff,SIZE,fp) != NULL) { //検索文字があれば if(strstr(buff, key) != NULL) { //検索文字とfile posiion を出力する printf("%s %d\n", pref[i], seek_point); //ただし、次の file position が eof で有るならば loop 脱 if(++i >= ALL) break; //次の検索文字をセット key = pref[i]; } //現在の file position をセット seek_point = ftell(fp); // while() の先頭へ } fclose(fp); return 0; }

yamaomoto
質問者

補足

ありがとうございます。参考にさせていただきました。

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

その他の回答 (5)

回答No.5

test.csvファイルは「 "" 」のダブルクォーテーションを省いた   a,b,c,d   e,f,g,h   i,j,k,l   m,n,o,p   q,r,s,t   u,v,w,x   あ,い,う,え   か,き,く,け   さ,し,す,せ   た,ち,つ,て とするとき、コマンドラインから「 ./a.out r 」と入力することで検索できます。a.out に続く引数を b,f,j,n,r,vとそれぞれ引数を換えて実行してみてください。 /* これは回答プログラムです */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME "test.csv" #define SIZE 32 #define ALL 6 struct tb{ char a[SIZE]; char b[SIZE]; char c[SIZE]; char d[SIZE]; }; struct set2 { char word[4]; long offset; }; int main(int argc, char *argv[]) { struct tb test; FILE *fp; char buff[SIZE]; long pos; int i; char *search; //検索文字 struct set2 table[ALL]= { //abcのみで失礼 "b",0, "f",8, "j",16, "n",24, "r",32, "v",40 }; if(argc!=2) return 1; search=argv[1]; fp=fopen(NAME,"r"); //データ・テーブルからオフセット値を得る for(i = 0; i < ALL; i++) if(strstr(search, table[i].word) != NULL) break; if(i >= ALL){ fclose(fp); return -1; } pos = table[i].offset; //ヘッドを移動する fseek(fp,pos,SEEK_SET); //メイン処理(文字記憶位置が指定されることから whileは不要) fgets(buff,SIZE,fp); //各項目の設定 strcpy(test.a,strtok(buff,",\"")); strcpy(test.b,strtok(NULL,",\"")); strcpy(test.c,strtok(NULL,",\"")); strcpy(test.d,strtok(NULL,",\"")); fclose(fp); printf("%s %s %s %s \n",test.a,test.b,test.c,test.d); return 0; } これに使われた table の offset 値は以下のプログラムから求められたものです。 /* これは参考プログラムです */ #include <stdio.h> #include <string.h> #define SIZE 128 #define ALL 10 int main(void) { char buff[SIZE]; int seek_point, i = 0; FILE *fp; char *key, *pref[] = {"b","f","j","n","r","v","い","き","し","ち"}; fp = fopen("test.csv", "r"); key = pref[i]; seek_point = ftell(fp); while(fgets(buff,SIZE,fp) != NULL) { if(strstr(buff, key) != NULL) { printf("%s %d\n", pref[i], seek_point); if(++i >= ALL) break; key = pref[i]; } seek_point = ftell(fp); } fclose(fp); return 0; }

すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

> pos=ftell(fp); > fseek(fp,pos,SEEK_SET); この行、意味無いように思えるんですが。 それから、 fopenを付け加えるのは、この ps=ftell(fp); の前である必要がありますが、それは大丈夫ですか? 「whileの前」が直前の意味だったら、 ftellが不正なfpに対して実行されるので誤動作する可能性が高いですが。

yamaomoto
質問者

補足

ありがとうございます。参考にさせていただきました。

すると、全ての回答が全文表示されます。
  • Hardking
  • ベストアンサー率45% (73/160)
回答No.3

strtokの¥は不要だと思います。 strcpy(test.a,strtok(buff,",")); strcpy(test.b,strtok(NULL,",")); strcpy(test.c,strtok(NULL,",")); strcpy(test.d,strtok(NULL,","));

yamaomoto
質問者

補足

「"」も削除しちゃいたいのでこれでいいかとは思いますが・・・

すると、全ての回答が全文表示されます。
  • anicicle
  • ベストアンサー率36% (129/356)
回答No.2

>Segmentation faultでてしまいました。 「Segmentation fault」はメモリアクセスに問題がある場合に発生する。 ここで問題が出る可能性があるのは、バッファ操作を行うstrcpy()とstrtok()。 その部分を重点的に見直すこと。

すると、全ての回答が全文表示されます。
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

ファイルをオープンしている処理と、ファイルをクローズしている処理が見当たりませんよ。

yamaomoto
質問者

お礼

訂正 >>while文の後に while文の前にでした

yamaomoto
質問者

補足

初歩的でしたね。しかし、 while文の後に if((fp=fopen(NAME,"r"))==NULL){ printf("ファイル%sが開けません\n",NAME); return -1; } と whileを抜けた後にfcloseして、コンパイル・実行しましたが、Segmentation faultでてしまいました。

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