• 締切済み

C言語でのカンマ区切りについて

結果テキストファイルから特定の値のみ抽出するプログラムを作成しているのですが、思うように動いてくれません。どなたか教えてくださいませんか。お願いします。 <テキストファイルの形式> 様々な文字や記号slm,0.070000,-53458.000000様々な文字や記号 これが1行に4つ程含まれるものが10行ほどあるのですが、 2つ目のカンマの後の数値部分のみ抽出したいのです。 <プログラム> char line[MAXLINE]; char a1[]="slm"; char *r; char *s[2]; while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line, a1)!=NULL){ for (r = line ;r = strstr(r, a1); r += 27 ){ for(int p=0;p>2;p++){ s[p]=strtok( strstr(r, a1), "," ); printf("%s",s[3]); } } printf(" \n"); i++; } } そこでこのようなプログラムを作ってみたのですが、実行すると何も表示されません。 どなたか改善策を教えてください。本当に困っています。

みんなの回答

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.7

> こちらのdouble型のaとbは何のための配列なのでしょうか? 配列と書いたのは > これが1行に4つ程含まれるものが10行ほどあるのですが、 とあったので、それら全部を記憶しておく必要があるなら、配列とか用意するように修正してください。という意味で、a, b 自体配列でもなんでもありません。あくまでサンプルコードとして提示してみただけで、こちらとしては数値に変換していいのかどうかも知りません。 ですから文字列として処理する必要があるなら、全然見当外れとなります。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.6

> char *s[3]; > strcpy(s[p],strtok( NULL, ",") ); これは値不定のポインタ配列 s[3] に、いきなり strtok() の返り値のアドレスからコピーしようということです。本当に内容をコピーして保存したいなら s[] のそれぞれに実体を与えてからじゃなきゃダメです。 それに strtok() 使うなら char *q; for (q = r; q = strtok(q, ","); q = NULL) { みたいに 2 回目以降の呼び出しを NULL にしなければなりません。 ただ最終的に数値として取り込みたいなら double a, b; for (r = line ;r = strstr(r, a1); r += i) { if (sscanf(r, "slm ,%lf ,%lf%n", &a, &b, &i) < 2) i = sizeof(a1)-1; あとは配列に追加してくなり、その場で加工するなり。

saruhara
質問者

補足

回答ありがとうございます。 double a, b; for (r = line ;r = strstr(r, a1); r += i) { if (sscanf(r, "slm ,%lf ,%lf%n", &a, &b, &i) < 2) i = sizeof(a1)-1; こちらのdouble型のaとbは何のための配列なのでしょうか? 何度もすみませんがご教授願います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

とりあえず 1点: strtok の使い方を確認してください.

saruhara
質問者

補足

回答ありがとうございます。勉強してみます。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

それから、配列の基本もおわかりではないようですね。 >char *s[2]; という定義で、正しく参照できるのは、s[0]とs[1]の「2個」です。 定義時の*s[2]は、0番から始まる「2個の領域」という意味です。 したがって、 >printf("%s",s[2]); s[2]は定義範囲外の領域です。また、ループの中で毎回出力しているのは意図が不明です。

saruhara
質問者

補足

詳しい回答を何度もありがとうございます! ご指摘くださった部分を改良して #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXLINE 2094 int main(void){ FILE *fp; int i=1; char line[MAXLINE]; char a1[]="SIL"; char a2[]="acoustic="; char *r; char *s[3]; /* ファイルオープン */ if ((fp = fopen( "C:\\Users\\石原慎也\\Desktop\\N_best.result", "r" )) == NULL){ printf("ファイルオープンに失敗しました。B\n"); exit(1); } /* データ処理 */ while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line, a1)!=NULL){ for (r = line ;r = strstr(r, a1); r += 27 ){ for(int p=1;p<=2;p++){ strcpy(s[p],strtok( NULL, ",") ); printf("%s",s[2]); } } printf(" \n"); i++; } } } という風にしてみたんですが、プログラムが動きません・・。 他にどこか悪いところありますか? 何度もごめんなさい。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

>for(int p=1;p>2;p++){ いや、ですからね、質問者さんはfor文の継続条件を勘違いされていると思うんですよ。 p>2 というのは、「pが2より大きい間」という意味です。 「pが2より大きくなるまで」という意味「ではありません」。

回答No.2

strstr()の引数が、反対です。 ファイルポインタはどこで定義されていますか? 一部ではなく、プログラム全体を掲載してほしいです。

saruhara
質問者

補足

#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXLINE 2094 int main(void){ FILE *fp; int i=1; char line[MAXLINE]; char a1[]="slm"; char *r; char *s[2]; /* ファイルオープン */ if ((fp = fopen( "ファイルへのダイレクトパス", "r" )) == NULL){ printf("ファイルオープンに失敗しました。B\n"); exit(1); } /* データ処理 */ while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line, a1)!=NULL){ for (r = line ;r = strstr(r, a1); r += 27 ){ strcpy(s[0],strtok( strstr(r, a1), ",") ); for(int p=1;p>2;p++){ strcpy(s[p],strtok( NULL, ",") ); printf("%s",s[2]); } } printf(" \n"); i++; } } } 回答ありがとうございます。こちらが全体のプログラムなんですが・・・。少々変えました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

for文の中の不等号の向きは正しいですか? s[3] は、配列の定義範囲外の領域です。アクセスして大丈夫ですか?

saruhara
質問者

補足

回答ありがとうございます。 すいません。間違えていました。 ですが直してもまだできません・・・。

関連するQ&A

  • C言語でファイルから特定の文字を抽出

    現在C言語でプログラム開発しています。 文字列が並んだテキストファイルから特定の部分のみを抽出したいのですが、うまくいきません。 お力を貸していただけないでしょうか。 テキストファイルの構造はこんな感じです。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 文字列 文字列 文字列badresult=*****文字列badresult=*****文字列badresult=*****文字列result=***** ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー これが10セット程記述されたファイルです。 ここから全てのbadresultの数値とresultの数値を抽出したいのです。 私が現段階で作成したプログラムがこちらです。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXLINE 2084 int main(void){ FILE *fp; char line[MAXLINE]; char s1[]="badresult"; char s2[]="result="; char *r; if ((fp = fopen( "テキストファイルへのダイレクトパス", "r" )) == NULL){ printf("エラーメッセージB\n"); exit(1); } while (fgets(line, MAXLINE, fp) != NULL){ if(strstr(line,s1)!=NULL){ printf("%.27s",strstr(line, s1),"\n"); printf(" "); printf(strstr(line, s2)); } } } ですがこれだと1行に全てのbadresultが含まれているため、結果は ----------------------------- badresult=***** result=****** ----------------------------- とbadresultは1つしか出てきません。 strstrのポインタをどうにかできないかと考えたのですが、 私のC言語の知識も浅いためなかなかうまくできません。 Cプログラミングに精通している方、どうか改善策を教えていただけないでしょうか。 できればなるべく簡単な方法ですと助かります。

  • C言語 複数ファイル操作について

    Cプログラミング初心者です。 論文などの何行も文章があるようなテキストファイル(ここでは1.txtとします)と、他に予め単語をいくつか登録しているテキストファイル(2.txt)を開き、1.txtを最初の行から一行ごとに読み込み、2.txtの中にある単語が1つでもその一行の文章中に含まれていたらその一行の文章を出力し、また次の行においても2.txtの中にある単語のいずれかが含まれているかどうかを調べて含まれている場合は出力…含まれていない場合は出力せずに次の行へ…といったようにこれを1.txt内の最後の行まで繰り返し行うプログラムを作りたいのですが、自分が作ったプログラムでは含む・含まない関係なく1.txt内の文章全てが出力されてしまいます。おそらく最初のwhile文あたりがおかしいのだろうという予想はつくのですがどのように直せばよいのかわからず悩んでいます。どなたか教えていただければ嬉しいです(;_:) #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1056 void delkaigyo(char *s1,char *s2){ char *p = s1; p=strstr(s1,s2); if(p!=NULL){ strcpy(p,p+strlen(s2)); delkaigyo(p+1,s2); } } int main(void){ FILE *fp; char *filename = "2.txt"; char str1[N]; char str2[N]; char kaigyo[] = "\n"; int i; int a=0; char fname[64]; printf("file:"); scanf("%s", fname);   ←ここで1.txtを入力するとします fp = fopen(fname, "r"); while(fgets(str1, N, fp) != NULL){ delkaigyo(str1, kaigyo); memset(str1, 0, N); fread(str1, 1, N-1, fp); if((fp = fopen(filename, "r")) == NULL){ fprintf(stderr, "%serror.\n", filename); exit(EXIT_FAILURE); } while(fgets(str2, N, fp) != NULL){ delkaigyo(str2,kaigyo); if(strstr(str1,str2)!=NULL){ a = 1; printf("%s\n", str1); break; } } if(a==0){ return 0; } fclose(fp); } return EXIT_SUCCESS; }

  • C言語に詳しい方お願い致しいます

    文字列Aから文字列Bを除いた結果を表示するプログラムなのですが 一ヶ所分からない部分があります。 #include <stdio.h> #include <string.h> int main(void){  char str1[] = "abcdefg";  char str2[] = "cde";  char str3[128] = "";  char *p1 = str1, *p2;  size_t len;  len = strlen(str2);  while((p2 = strstr(p1,str2)) != NULL) {   strncat(str3,p1,p2 - p1);   p1 = p2 + len;   printf("----\n");   printf("p2=%s\n", p2);   printf("str3=%s\n", str3);   printf("p1=%s\n", p1);  }  strcat(str3,p1);  printf("%s\n",str3);  return 0; } while文中の p1 = p2 + len; なのですが、何故これでp1の内容が「fg」になるのでしょう。

  • C言語 strstrの実装

    課題で strstr()と同じ働きをするmy_strstr()を実装しなさいという課題がでています。 strstr()は char *strstr(const char *s1, const char *s2) という形で、 文字列s2が文字列s1の中に含まれていれば、文字列1の文字列2が含まれている先頭のアドレス(ポインタ)を返す関数です。(すいません、説明が下手で) 例えば、 strstr(Japanese, pan)は Japanese にpan が 含まれるのでpan 以降の文字列を返します→panese *********************** 質問ですが、 strstrの実装は完成して、正常に動くのですが 警告がでてきます。 str1= Japanese str2 = pan とすると、 私のプログラムでは、次のようなプロセスで動きます。 一文字ずつ調べる ↓ str1のJと str2の pを比較        J != p → str1++; //str1の次の文字へ str1のaと str2の pを比較        a != p, str1++; //str1の次の文字へ str1のpと str2の pを比較        p == p, rec = str1 // str1のアドレスを記録         str1++; str2++; //次の文字へ str1のaと str2の aを比較        a == a, str1++; str2++; //次の文字へ str1のnと str2の nを比較        n == n, str1++; str2++; //次の文字へ str1のeと str2 nullを比較    *str2 = null //search 終了。 return rec; とこんな感じです。 このプロセスの3行目の rec = str1; つまり、関数の戻り値のために記録したstr1のところで、 「問題のあるポインタ変換」 という警告がでます。 これは s1がconstだからでしょうか? どのようにしたらこの警告が消えるでしょうか? どなたかよろしければアドバイスをいただけませんか。 お願いします。

  • C言語でセグメンテーションエラーの原因がわからず困っています。

    こんにちは。いつもお世話になっております。 C言語なのですが、何故かプログラムを実行するとセグメンテーション違反が表示されてしまい全く動きません。皆さんのお力を貸して頂けないでしょうか。 以下が問題のプログラムです。 前提条件: ・別プログラムによりfile.txtは末尾に文章が追加され続けている ・本プログラムは永劫的に動き続ける #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<errno.h> #include<signal.h> #include<sys/types.h> int main () { int i = 1, a; FILE *fp, *fp2; char *tok; //NULLを入れて初期化 char buf[1024] = ""; char str[1024] = ""; char str2[1024] = ""; //出力するファイルを開く if ((fp2 = fopen ("out.txt", "a")) == NULL) { printf ("out.txt:open error\n"); exit (-1); } while (1) { //何度もfopenするのでループ二週目以降は一旦fpを閉じる if (str2 != NULL) { fclose (fp); } //一度読み込み、2週目以降もさらに読み込み続ける if ((fp = fopen ("file.txt", "r")) == NULL) { printf ("file.txt:open error\n"); exit (-1); } //str2はループ2週目以降で使われる if (str2 != NULL) { while (1) //新しい行を見つけ出す { fgets (str, 1024, fp); if (strstr (str, str2) != NULL) { printf ("前回の最終行です:%s\n", str); break; } } } else { printf ("str2はNULLです:%s\n", str2); } //fopenで読み込んだ現段階のテキストファイルをout.txtに移す while (1) { if( (fgets (str, 1024, fp) ) == NULL)break; if ((a = strlen (str)) >= 2) { str[a - 1] = '\0'; } else { printf ("抽出した文字列が1文字以下です:%s\n", str); break; } if (strlen (str) >= 17) { strcpy (str2, str); } else { printf ("抽出した文字列が16文字以下です:%s\n", str); break; } printf ("%s\n", buf); fprintf (fp2, "%s\n", buf); strcpy (buf, ""); strcpy (str2, str); } printf ("これが検索語です:%s\n", str2); } fclose (fp2); return 0; } プログラムの内容は、 更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。(file.txtの内容を若干変えつつ、out.txtに出力することが本来の目的ですが、その部分は省略させて頂きました。) fopenで開くと、「その時点まで」のfile.txtしか開かれません。更新され続けているfile.txtの内容をコンスタントに読み取る為に、while文でfopenし続ける方法を取っていますが、そうするとout.txtに移し終わった行まで読み込んでしまい重複した文章をout.txtに移すことになりますので、strstrを使い、「前回fopenで開いたfile.txt」の最終行を検索してその位置からまたout.txtに移す、という方法を取りました。しかし、結果は何故かセグメンテーション違反でした。 以上のプログラムや私の意図する所で何か気づかれた点や、おかしいと思われた点等ありましたら是非ご教授頂きたく思います。 どんな些細なことでも構いませんので、教えて頂けないでしょうか。 環境はCentosです。どうぞよろしくお願いします。

  • c言語プログラミング実行時エラーについて質問です。

    c言語プログラミングを実行しようとすると、 エラーが出て次のようなメッセージが出てしまいました。 「「7行目」で記述エラーを発見しました。「constant expression」を付け忘れています。」 どなたか原因を教えてください。よろしくお願いいたします。 以下が失敗したプログラムです。 #include <stdio.h> int main(int argc, const char * argv[]) { const char FILENAME[] = "/Users/user/Desktop/date3.txt"; const int LEN = 100; char line [LEN]; char name [LEN]; char birth [LEN]; char address [LEN]; FILE *dat; dat = fopen(FILENAME, "r"); if ( dat == NULL ) { printf(" ファイル %s がオープンできません. ", FILENAME); return -1; } while( fgets( line, LEN, dat) != NULL ) { sscanf( line "%s, %s, %s", name ,birth, address ); printf("name = %s, address = %s\n", name, address ); } fclose(dat); return 0; }

  • c言語のscanfとfgetsについて

    2つの単語A, Bを入力して、AがBに含まれるか否かというプログラムで 以下のようなものを作成しました。 そこで質問なのですがscanf()をfgets()に変えるとうまく動作しません どこが間違ってますか? 変更したいfgets fgets(key, sizeof(key), stdin); fgets(word, sizeof(word), stdin); ------------------------------------------------- int main(void) { char key[101], word[101]; scanf("%s", key); scanf("%*c%s", word); if (strstr(word, key) != NULL) { printf("Find %s In %s\n", key, word); } else { printf("Not Find\n"); } return 0; }

  • C言語 説明文

    C言語(文字列のコピーについて) /* 文字列のコピーを行う関数の実現例 動作原理のコメントを書き入れる */ #include <stdio.h> /*-----文字列のコピー(1)-----*/ char *scpy1 (char *d, const char *s) { int i = 0; while ((d[i] = s[i]) != '\0') { i++; } return(d); } /*-----文字列のコピー(2)-----*/ char *scpy2 (char *d, const char *s) { char *p = d; while ((*d = *s) != '\0') { d++; s++; } return(p); } /*-----文字列のコピー(3)-----*/ char *scpy3 (char *d, const char *s) { char *p = d; while ((*d++ = *s++) != '\0') { ; } return(p); } /*-----文字列のコピー(4)-----*/ char *scpy4 (char *d, const char *s) { char *p = d; while (*d++ = *s++) { ; } return(p); } int main(void) { char astr[] = "ABC"; char bstr[8], cstr[8], dstr[8],estr[8]; scpy1 (bstr, astr); scpy2 (cstr, astr); scpy3 (dstr, astr); scpy4 (estr, astr); printf("astr = %s\n" , astr); printf("bstr = %s\n" , bstr); printf("cstr = %s\n" , cstr); printf("dstr = %s\n" , dstr); printf("estr = %s\n" , estr); return (0); } ----------------------- このプログラムに、この行で何をやっているのかわかるように 一言くらいの説明文を入れる問題です。 ところどころはわかるのですが、わからないところの方が多いです。 プログラムが長くて大変かとは思いますが、どうかよろしくお願いいたします。 このプログラム自体はちゃんとコンパイルでき、実行もできたので おそらく間違いないと思います。

  • C言語→C#に変換

    C言語→C#に変換 C言語からC#に変換したいのですが、わからないところがあります。 コマンドライン引数からファイル名とキーワードを入力して、キーワードがある行をアウトプットファイルに書き込むという処理です。 C言語のソースは、 main(int argc,char *argv[]){ FILE *fp; FILE *fpp; int i; char KEYWORD[256]; char buf[256]; //(1)アウトプットファイルのオープン fpp=fopen("output.txt","w"); for(i=1;i<argc-1;i++){ if(strcmp(argv[i],"-a")==0){ //(2)入力ファイルのオープン if((fp=fopen(argv[i],"r"))==NULL){ printf("open error!\n"); exit(1); } } //(3)キーワードの代入 if(strcmp(argv[i],"-b")==0){ strcpy(KEYWORD,argv[i]); } } //(4)一行読み込む while(fgets(buf,sizeof(buf),fp)!=NULL){ //(5)キーワードの条件で文字列抽出 if(strstr(buf,KEYWORD)!=NULL){ //(6)アウトプットファイルに出力 fprintf(fpp,"%s",buf); } } //ファイルクローズ fclose(fp); fclose(fpp); } です。 (3)キーワードの代入と、(5)文字列抽出の部分がネットなどで調べてもよくわかりません。 分かる方いらっしゃいましたら教えていただけると幸いです。 宜しくお願いします。 .

  • C言語 教えてください

    data.txtの中に入っているデータを読み込み、 全て出力するというプログラムを作ろうとしています。 しかし、上手く読み込み表示させることが出来ません。 自分で出来るだけ調べたのですが、 どこがおかしいのかわからないので教えてください。 ↓↓↓現在作っているプログラムです↓↓↓ #include <stdio.h> void main(void) { FILE *fp; char number, name; if ((fp = fopen("data.txt", "r")) == NULL) { printf("FILE OPEN ERROR\n"); } else { while (fscanf(fp, "%s%s", number, name) == 2) { printf("%s-%s\n", number, name); } } fclose(fp); printf("FILE CLOSE !!\n"); } ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↓↓data.txt↓↓ 001 aaa 002 bbb 003 ccc 004 ddd 005 eee ↑↑↑↑↑↑↑↑ よろしくお願いします。

専門家に質問してみよう