dポイントプレゼントキャンペーン実施中!

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"
"あ","い","う","え"
"か","き","く","け"
"さ","し","す","せ"
"た","ち","つ","て"

とし、真ん中のq,r,s,t以降の内容を表示させたく、下のようなプログラムを作成しました
しかし、コンパイル後実行しようとするとエラーになってしまいます。どう直したらよいか教えて頂けますでしょうか?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME "test.csv"
#define SIZE 32

struct tb{
char a[SIZE];
char b[SIZE];
char c[SIZE];
char d[SIZE];
};

int main(void)
{
struct tb test;
FILE *fp;
char buff[SIZE];
long pos;

pos=ftell(fp);
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,",\""));

printf("%s %s %s %s \n",test.a,test.b,test.c,test.d);
}
}

A 回答 (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;
}

この回答への補足

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

補足日時:2010/04/22 16:02
    • good
    • 1

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;
}
    • good
    • 0

> pos=ftell(fp);


> fseek(fp,pos,SEEK_SET);

この行、意味無いように思えるんですが。

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

この回答への補足

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

補足日時:2010/04/22 16:02
    • good
    • 0

strtokの¥は不要だと思います。


strcpy(test.a,strtok(buff,","));
strcpy(test.b,strtok(NULL,","));
strcpy(test.c,strtok(NULL,","));
strcpy(test.d,strtok(NULL,","));

この回答への補足

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

補足日時:2010/04/21 17:17
    • good
    • 0

>Segmentation faultでてしまいました。


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

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

この回答への補足

初歩的でしたね。しかし、

while文の後に
if((fp=fopen(NAME,"r"))==NULL){
printf("ファイル%sが開けません\n",NAME);
return -1;
}

whileを抜けた後にfcloseして、コンパイル・実行しましたが、Segmentation faultでてしまいました。

補足日時:2010/04/21 13:44
    • good
    • 0
この回答へのお礼

訂正
>>while文の後に

while文の前にでした

お礼日時:2010/04/21 14:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!