• ベストアンサー

C言語のsscanf関数の上手な使い方2

質問NO.60489の追加です。 C言語で、 char buf[256] = "\"aa, aa\",100,\"bb bb\",200,\"cc-cc\"; char c1[10],c2[10],c3[10]; int i1,i2; のとき、 c1 = "aa, aa" c2 = "bb bb" c3 = "cc-cc" i1=100 i2=200 に読み込みたいのですが、 sscanf(buf,"\"%[^\"]\",%d,\"%[^\"]\",%d,\"%[^\"]\"",c1,i1,c2,i2,c3); では失敗します。 sscanfのformat部分をどのように書いたらよいか分かりません。

  • yasu1
  • お礼率20% (2/10)

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

  • ベストアンサー
  • funi2
  • ベストアンサー率53% (14/26)
回答No.2

基本的にあっていると思います。基本的にというのは, char buf[]...の行に"が1個足りない。sscanfでi1, i2がそれぞれポインタで呼ばれていない。の2点が間違っていると思います。それ以外では間違っていないからです。 ちょっと質問なのですが, c1に"も含めるのですか?そうすると, ちょっとわかりません。 自分がやった結果をちょっと長いですが載せたいと思います。 /* sscanf.c */ #include<stdio.h> int main(void){ char buf[256] = "\"aa, aa\",100,\"bb bb\",200,\"cc-cc\""; /* ちょっと変更を加えた。 */ char c1[10],c2[10],c3[10]; int i1,i2; sscanf(buf,"\"%[^\"]\",%d,\"%[^\"]\",%d,\"%[^\"\"",c1,&i1,c2,&i2,c3); /* ちょっと変更を加えた。*/ puts(c1); puts(c2); puts(c3); printf("%d, %d", i1, i2); return 0; } /* 実行結果 $はプロンプト $ sscanf aa, aa bb bb cc-cc 100, 200$ */

yasu1
質問者

お礼

ご回答ありがとうございます。 単純なミスでした。 sscanfで、&i1, &i2になっていませんでした。 急いでいたので、ありがとうございました。

その他の回答 (1)

  • kazuya-i
  • ベストアンサー率21% (7/32)
回答No.1

物の本を読むとscanf系は使わないほうがいいって出てませんか? 想定外の文字がくると動作がおかしいから かな 自前で関数を作ったほうがいいと思います。 文字列の長さのチェックもしてくれないし(^^

関連するQ&A

  • C言語のsscanf関数の上手な使い方

    C言語で、 char buf[256]; char c1[10],c2[10],c3[10]; sscanf(buf,"%s%s%s",c1,c2,c3) という、バッファから文字列を読み取るとき、 bufが、 "aa bb","aa,bb","aa, bb"の場合に、 c1 = "aa bb" c2 = "aa,bb" c3 = "aa, bb" が入るようにする方法をご存知でしたら教えてください。 %[^\"]sを使ってみたのですが、c1しか格納できませんでした。 (条件) " "かつ,で区切られた部分をパラメタに格納する。 " "内には、空白や,が入る。

  • sscanfの使い方について

    char *str = ./aa...a/b..bb/cc..c/d...dd.txt"; の aa...a , b..bb , cc..c , d...dd を取り出したいのですが sscanf(str,"./%s/%s/%s/%s.txt",a,b,c,d); とすると,aだけにすべての文字列が入ってしまい,他のb,c,dには何も入りません. つまり.a = "aa...a/b..bb/cc..c/d...dd.txt" となります. a,b,c,dはいずれも char a[512],b[512],c[512],d[512] となっております. 取り出すうまい方法がありましたら教えてください.

  • fgets, sscanf, バッファ、ストリーム について

    ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。 そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。 例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。 どうぞ、よろしくお願いします。 (データファイル test.dat) n_data 4 1 3 8 4 (プログラム) #include <stdio.h> main() { int i, n_data, *data; char buf[100]; FILE *fp; fp = fopen ( "test.dat", "r" ); fgets(buf, 100, fp); sscanf( buf, "n_data %d\n", &n_data ); data = (int *)malloc( n_data * sizeof(int) ); for( i=0; i<n_data; i++ ){ fgets(buf, 100, fp); sscanf( buf, "%d", &(data[i]) ); } sscanf( buf, "\n" ); close( fp ); printf( "n_data %d\n", n_data ); for( i=0; i<n_data; i++ ) printf( " %d", data[i] ); printf( "\n" ); } ちなみに、2行の fgets(buf, 100, fp); をコメントアウトして、 "sscanf( buf," を "fscanf( fp," に変更するとうまく動作します。

  • sscanf() 関数の第 1 引数の型

     カーニハン/リッチー・著,石田晴久・訳の「プログラミング言語 C・第 2 版」で,「付録 B」にある sscanf() 関数のプロトタイプが   int sscanf(char *s, const char *format, ...) とあって,疑問に思いました。この第 1 引数の型は,「char *」ではなくで「const char *」のほうが合理的のように思えるのです。JIS X 3010-2003 では,const がついていましたし,さまざまな解説・マニュアルでも const つきで示されています。  そこで,ANSI C または JIS X3010-1993 の仕様書をお持ちの方,それらの仕様書の中で sscanf() 関数がどのようなプロトタイプを持っているか,ご教示願えませんでしょうか。ひょっとしたら本当に const がついていないのかもしれないし,書籍から何らかの理由で const が抜け落ちてしまったのかもしれません。  細かい点で恐縮ですが,ご回答くだされば幸いです。

  • fgetsとsscanfの使い方

    初歩的な質問で申し訳ないのですが、fgetsとsscanfの使い方が合っているか確認願います fgets(char *s , int n ,FILE *fp); -> fpから1行(nで指定した文字数)読み込み、sに格納する sscanf(char buf, "%s", char string); -> bufから%sを読み込み、stringに格納する まだ使い慣れていないのでどっちから読み込むのかこんがらがってます 上記の解釈でよろしいのでしょうか?

  • scanf()関数の使い方について

    はじめまして。 質問があります。 以下のコードを見てください。 ---------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> int main(void) { int i; char buf[256]; int y; int m; int d; printf("文字列を入力してください:"); scanf("%s",buf); i = sscanf(buf,"%d/%d/%d",&y,&m,&d); //OK #if 0 i = sscanf(buf,"%d %d %d",&y,&m,&d); //NG #endif printf("日付 %d-%d-%d 戻り値i=%d\n",y,m,d,i); return EXIT_SUCCESS; } ---------------------------------------------------------------- 標準入力から日付を表す文字列「例:"2007/04/17"」を入力してbufに 格納したものをsscanf関数の第1引数に指定して、y,m,dを表示 させてみると、「i = sscanf(buf,"%d/%d/%d",&y,&m,&d)」では、 うまくyとmとdに日付が格納される(つまり、yに2007が入り、mには 04が入り、dには17が入る。)のですが、 「i = sscanf(buf,"%d %d %d",&y,&m,&d);」でbufに格納すると、 yにはうまく格納されるのですが、他のmとdには、うまく格納してくれ ません。これは、なぜなのでしょうか? ご教授お願いします。

  • C言語 sscanf関数で変換に失敗した場合

    sscanf関数で変換に失敗した場合という点がよくわからなかったため、 質問させていただきます。 入力された整数の2乗を返すプログラム --------------------------------------------------- # include <stdio.h> # define BUFSIZE 256 int main(void) {   int input;   char linebuf[BUFSIZE];   printf("整数を入力してください。\n");   while(fgets(linebuf, BUFSIZE, stdin) != NULL) {     if(sscanf(linebuf, "%d", &input) != 0) {       printf("%dの2乗は%dです。\n", input, input*input);       break;     }     else {       printf("整数を入力してください。\n");     }   }   return 0; } ----------------------------------------------------- 例えば、入力された値が文字列であった場合、 if(sscanf(linebuf, "%d", &input) != 0) の文のところで"%d"と整数を指定しているため、 変数inputに入力された値を格納できません。 sscanf関数は変換エラーの場合は「EOF」を返すとなっているにもかかわらず、 ここでは「0」以外の場合(!= 0)となっています。 変換エラーというのは、入力された値とsscanf関数で指定した書式が異なる場合は含まないのでしょうか。 そうであるならば、変換エラーというのはどのようなものなのでしょうか。 ちなみに、「!= 0」の部分を「!= EOF」にして実行したところ、 無関係な数値が出力されました。 (aを入力したら、4198555の2乗は~と出力されました)

  • sscanf エラー

    sscanfで整数が読み込めません。 コマンドプロンプトの画面は以下のようです。 文章を入力してください。 aaaa 11 14 aaaa 4201776 4201870 1 以下が実行したコードです。 #include<stdio.h> int main(void){ int a,b,c,i; char name[20]; printf("文章を入力してください。\n"); scanf("%s",x); c=sscanf(x,"%s %d %d",name,&a,&b); printf("%s %d %d %d\n",name,a,b,c); return(0);} aaaa 11 14と表示されるように、御指摘おねがいします。

  • 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)文字列抽出の部分がネットなどで調べてもよくわかりません。 分かる方いらっしゃいましたら教えていただけると幸いです。 宜しくお願いします。 .

  • sscanfでフォーマットに合っているかを調べるには。

    今,Cの関数で0-9,A-Zの4文字以内の文字列かどうか を調べたいのですが, int main() { int i; char str[] = "ABCD" /* 調べたい文字列1 */ char str1[]= "ABC@" /* 調べたい文字列1 */ char str2[]= "ABCDE" /* 調べたい文字列1 */ char *p; p = str; /* ここをstr1,str2に変える */ if (strlen(p) != 4) printf("エラーです\n"); for (i = 0; i < 4; i++) { if (!isupper(p[i]) && !isdigit(p[i])) { printf("えらーです\n"); return EXIT_FAILURE; } } printf("すべてOKです\n"); return EXIT_SUCCESS; } というようにすれば,strとstr1とstr2がフォーマットに合うかわかるのですが,これをsscanfの正規表現を使用して実装したいのですが,可能でしょうか。 int main() { int ret; char str[] = "ABCD" /* 調べたい文字列1 */ char str1[]= "ABC@" /* 調べたい文字列1 */ char str2[]= "ABCDE" /* 調べたい文字列1 */ char *p; chat tmp[30]; p = str; ret = sscanf(p, "%4[0-9A-Z]", tmp); if (ret != 1) { printf("エラーです\n"); return EXIT_FAILURE; } printf("すべてOKです\n"); return EXIT_SUCCESS; } といしょうとするならば,str1のときは,@までのABCの文字列がとれて,retには1が帰ってきてしまいます。 なにか4文字以内ということを実装できる正規表現の使い方はあるのでしょうか? ちなみに sscanf(str, "%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]", tmp1, tmp2, tmp3, tmp4) という以外でわかる方,よろしくおねがいします。

専門家に質問してみよう