• ベストアンサー

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には、うまく格納してくれ ません。これは、なぜなのでしょうか? ご教授お願いします。

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

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

"%d %d %d"という書式文字列と実際の入力"2007/04/17"とが 合わなくなったときにsscanf()は停止します。 合わなくなったとき、とは、"/"を検知したときです。 "/"を検知する前に、yには2007という値を格納済みです。 sscanfが停止した時点で、mとdは不定のままです。

takeshix100
質問者

お礼

asuncion様へ ご回答ありがとうございました。 大変勉強になりました。 ありがとうございました。

takeshix100
質問者

補足

asuncion様へ ご回答ありがとうございました。 質問を投稿後すぐにご返事がきていたとは思わずご返事がおくれました。もうしわけありません。悪戦苦闘しておりました。 どうしてもわからず、もう一つだけ質問させてください。 以下のコードを見てください。 ---------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> int main(void) { int i; char buf[256]; int y; int m; int d; char mon[20]; printf("文字列を入力してください:"); scanf("%s",buf); i = sscanf(buf,"%d %s %d",&d , mon , &y); printf("日付 %d-%s-%d 戻り値i=%d\n",d ,mon,y,i); return EXIT_SUCCESS; } ---------------------------------------------------------------- 標準入力から日付を表す文字列「例:"17 April 2007"」を入力して bufに格納したものをsscanf関数の第1引数に指定して、d,mon,yを表示 させてみると、最初のdが表示されるのですが、残りのmonとyが うまく表示されません。確かに"%d %s %d"という書式文字列と実際の入力"17 April 2007"を合わせてみたのですが、うまく表示されません。なぜなのでしょうか?ご教授お願いします。

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

その他の回答 (1)

  • tea_sheep
  • ベストアンサー率53% (8/15)
回答No.2

%s指定は空白文字で区切られるため「scanf("%s",buf);」という記述では入力された 「17 April 2007」のうち最初の空白までの「17」しかbufに格納されません。 そのため、後に続くsscanfでもその「17」しか取得されないのです。 この場合は scanf("%s",buf); の代わりに fgets(buf,sizeof(buf),stdin); などを使用します。

takeshix100
質問者

お礼

tea_sheep様へ ご回答ありがとうございました。 問題解決しました。 すっきりしました。 勉強になりました。 2つのご回答とも大変勉強になりまして 両者様ともに20点を与えたいのですが、 今回はご回答順で点数をつけさせていただきます。 大変申し訳ありません。

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

関連するQ&A

  • 空白を含んだ文字列がうまく格納(表示)できない

    こんにちわ。 空白(スペース)の入った文字列の格納(表示)について質問させてください。 以下のプログラムを実行すると、空白の含む文字列がうまく表示されません。 例えば、 in the worldと入力しても、inしか格納されていないみたいです。それはなぜでしょうか? また、どうすればそれを格納、表示させることができるのでしょうか?教えてください。よろしくお願いいたします。 #include <stdio.h> #include <string.h> main() { char buf[BUFSIZ]; char moji[31]; int i; printf("Input string: "); fgets(buf, sizeof(buf), stdin); moji[31] = '?0'; sscanf(buf, "%s", moji); i = 0; while (moji[i] != '?0') { printf("%c",moji[i]); i = i + 1; } printf("?n"); printf("%d letters?n", i); } 【実行例】 csx01:~> gcc prog.c csx01:~> a.out Input string: in the world in 2 letters

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

    はじめまして。 質問があります。 まずは、以下のコードを見てください。 ---------------------------------------------------------------- #include<stdio.h> int main(void) { char c; int i; printf("0を入力すると終了します。\n"); while(1) { printf("文字を入力してください=>"); scanf("%c",&c); printf("入力した文字は %c です。\n",c); printf("数字を入力してください=>"); scanf("%d",&i); if(i==0) { break; } printf("入力した数字は %d です。\n",i); } return 0; } ---------------------------------------------------------------- 上のコードを実行すると、初回はscanf()はcharとintの両方とも 入力待ちになってくれるのですが、2回目以降はcharは入力待ちに なってくれません。これは、なぜなのでしょうか? ご教授お願いします。 現在VC++6.0を使用しております。

  • scanf関数について

    scanfで数字を入力し「CTRL+D」で入力終了となるプログラムを考えています. 調べてみると以下の様なプログラムでは入力終了となります. #include <stdio.h> int main(void) { int a[256]; int i = 0; while(1) { printf("Input%d = ", i); if ( scanf("%d", &a[i]) == EOF || i > 255) { break; } i++; } return 0; } しかし,次の様にすると「CTRL+D」では終了しません. #include <stdio.h> int main(void) { int a[256]; int i = 0; while(1) { printf("Input%d = ", i);   scanf("%d", &a[i]); <-----追加 if ( a[i] == EOF || i > 255) {   <-----変更 break; } i++; } return 0; } この場合は,環境がUNIXのため「-1」と入力すると終了します. 2種類の違いが分かりません. 教えてもらえないでしょうか?

  • 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," に変更するとうまく動作します。

  • fgets関数を使用したときの文字あふれについて

    fgets関数を用いて文字列を入力し、その長さを測るプログラムを作っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main ( int, char *[] ); int main ( argc, argv ) int argc; char *argv[]; { char buf[( MAX )]; while ( 1 ){ memset ( buf, 0, sizeof( buf )); fgets ( buf, MAX, stdin ); if( fgets == NULL ){ break; } printf("入力した文字列の長さは%dです\n" ,strlen( buf )); } return 0; } このプログラムでは、256までしか文字列の長さを測ることができません。 もしこのプログラムで256を超える文字列を入力してしまうと、文字のあふれが発生し、 「入力した文字列の長さは256です」 「入力した文字列の長さは(あふれた文字列の長さ)です」 とこのようになってしまいます。 このプログラムで256以上の文字を読み捨てて、 「入力した文字列の長さは(あふれた文字列の長さ)です」 を表示しないようにできるのでしょうか? また読み捨てた文字列の長さを知ることはできるのでしょうか? もしかしたらfgets関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。

  • scanf が無視されます

    例えば下のようなプログラムを実行するとmain関数の scanf が無視 されてしまいますが何故なのでしょうか。コンパイラはLSI C-86試食版です。 ----------------------------- #include <stdio.h> int main ( ) ; void aa ( ) ; int main ( ) { int i ; aa ( ) ; printf ( " input i. \n " ) ; scanf ( " %d ", &i ) ; printf ( " i = %d\n ", i ) ; } void aa ( ) { int x, y ; while ( scanf ( " %d ", &x ) ! = EOF ) { y = x ; printf ( " y= %d\n ", y ) ; } } --------------------------------

  • scanfの後のfgetsについて

    #include <stdio.h> int main(void) { char name[10]; int no; printf("ナンバーを入力してください: "); scanf("%d",&no); /* 35を入力 */ printf("文字列を入力してください: "); fgets(name,10,stdin); /*入力できない*/ return 0; } この例文だと、fgets関数が改行コードを読み取って、終了してしまい文字列入力が出来ないみたいなんですが、scanfの後にfgetsを使うような(scanfとfgetsの間にscanfの残した?改行コードを取り除く方法)処理はどのような方法があるのでしょうか? 試しにfgets文を2度書いたら思っていた動作をしてくれたのですが、はたしてfgets文を2度書くというような事をしていいものなのでしょうか?見た目もなんだか変な感じですし。。↓ #include <stdio.h> int main(void) { char name[10]; int no; printf("ナンバーを入力してください: "); scanf("%d",&no); /* 35を入力 */ printf("文字列を入力してください: "); fgets(name,10,stdin); fgets(name,10,stdin);  /*入力できる*/ return 0; }

  • scanfの謎

    C言語の以下のプログラムがありまして、 #include <stdio.h> main() { int i; scanf("%d ", &i);printf("d=%d\n", i); } これを実行すると、 1 2 d=1 のように、入力を2回受け付けてしまいます。 一体なんでこのようなことが起こるのでしょうか?教えてください。

  • 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乗は~と出力されました)

  • C言語 atoi関数

    入力された年号と年数から(和暦)、西暦を算出するプログラムです。 年号の入力チェックのところが、どうしてもうまくいきません。  year_name = atoi( yn_buf ); year_name にatoi()で変換された値が入りません。 初期値のゼロのままです。その為、年号に何を入力してもエラーメッセージが表示されてしまいます。 atoi関数の使い方が間違っているのでしょうか? すみませんが、教えて下さい。 int year_name = 0; /* 年号を格納 */ int years = 0; /* 年数を格納 */ int check_flg = FALSE; /* 入力チェック 初期値としてエラー有状態とする*/ char yn_buf[32] = { '\0' }; /* 年号のチェック用 */ char y_buf[32] = { '\0' }; /* 年数のチェック用 */ printf( "<年号> 明治:m 大正:t 昭和:s 平成:h \n" ); printf( " 年号と年数を入力して下さい。 " ); scanf( "%s%s", &yn_buf, &y_buf ); printf("\n"); while( 1 ) /* 年号チェック */ { if( strlen( yn_buf ) >= 2 ) /* 年号が2文字以上の時、エラー */ { printf(" ▲エラーメッセージ 年号は1文字で入力して下さい。\n"); } else { year_name = atoi( yn_buf ); if( ( year_name == 'm' ) || ( year_name == 't' ) || ( year_name == 's' ) || ( year_name == 'h' ) ) { /* 年号が正しく入力されている時 */ break; } else { /* 年号が正しく入力されていない時 */ printf(" ▲エラーメッセージ 年号は、「 m, t, s, h 」のいずれかを入力して下さい。\n"); } } printf( " 年号を入力して下さい。 " ); scanf( "%s", &yn_buf ); printf("\n"); }

このQ&Aのポイント
  • 自宅で見つかったSYSTEM-100Mを久しぶりに鳴らすため、パッチケーブルや電源・CV用ケーブルを購入する必要があります。
  • モジュール用は8pin、キーボード用は6pinのDINケーブルを使用することができますが、プラグ形状や結線には注意が必要です。
  • ローランド製品やボス製品について、DINケーブルの独自仕様があるかどうか、詳しい情報を知りたいです。
回答を見る

専門家に質問してみよう