2013-08-28 9 views
6

は、以下のCコードスニペットを検討:差( "%のC"、&C)およびscanf( "%のC"、&C)

#include <stdio.h> 

int main() 
{ 
    int a; 
    char c; 
    scanf("%d",&a); 
    scanf("%c",&c); 
    printf("int=%d\n",a); 
    printf("char=%c\n",c); 
} 

私は整数ではなく、入力することができますよ出力は単純に整数値であり、2番目のprintfステートメントの値は出力されません。

しかし、私は書式指定子の前にスペースを使用する場合:

scanf(" %c",&c); 

期待どおりに動作します。これはなぜですか?

誰かが、入力バッファをクリアすることと関係があると教えてくれました。誰かが同じ光を放つことができるだろうか?

答えて

8

scanf("%c", &c1)scanf(" %c", &c2)の違いは、空白を含まないフォーマットは空白であっても次の文字を読み込みますが、空白を含むものは改行を含めて空白をスキップし、次の文字は読み込まないことです空白。

scanf()の形式では、空白、タブ、または改行は、スキップする場合は空白をスキップすることを意味します。直接 '入力バッファをクリアする'というわけではありませんが、入力バッファをクリアするのと同じように見えるホワイトスペースを食べています(しかし、それとは全く異なります)。 Windowsの場合、fflush(stdin)を使用すると入力バッファ(空白文字と空白以外の文字)が消去されます。 UnixではC標準によると、fflush(stdin)は未定義の動作です。

ちなみに、整数を入力した直後にキャリッジリターンが続くと、プログラムの出力は2つの改行で終了します。最初はcで、2番目は書式文字列です。このように、あなたが見ているかもしれません:

ある
$ ./your_program 
123 
int=123 
char= 

$ 

は、scanf()は、その入力として改行を読み込みます。

$ ./your_program 
123xyz 
int=123 
char=x 
$ 

「x」を読み込むと整数入力が停止しました。したがって、文字入力は 'x'を読み取ります。

+0

バッファのクリアとスキップの違いを教えてください。私はここでかなり混乱していますか? –

+0

違いは、スペリング、つまり 'ing'の前の5文字です。 「クリア」または「スキップ」には定義された意味はありません。私は意味を選択する場合、 'クリア'は明示的な作業ではプログラマを伴いますが、 'スキップ'はプログラマの明示的な作業なしで 'scanf()' - ファミリー関数の内部で行われますが、ディスカッションや他の人々は、コヒーレントに動作する正当な代替定義を持つかもしれません。 –

2

番号を入力してEnterキーを押すと、新しい行はバッファに残り、2番目のscanfで処理されるためです。

簡潔に言えば、変数cに新しい行を保存しました。あなたは

scanf(" %c",&c); 
// ^

使用する場合

しかし、スペースがcあなたが期待値になる新しい行を、消費します。あなたはフォーマット文字列で指定されたデータオブジェクトへのポインタを渡す必要が

-1

、そう

scanf("%c", c); 

実際に順番にプログラムの障害を引き起こす可能性がCの値を渡します、

scanf("%c", &c); 

はcのアドレスを渡し、scanfがあなたのコピーの値を変更できるようにします。

%cの後のスペースは、それが文字を探すのを強制し、その後はスペースを探します。空白がない場合、文字を読み取ることはありません

+1

これは、なぜスペースが 'scanf'を正しく動作させるのかという疑問に答えることさえしません。それに加えて、OPはscanf( "%c"、c) 'の使用を提案していません。 – user4815162342

+0

また、フォーマット文字列の末尾のスペースは、少なくとも対話型プログラムの場合は軽微な災害です。非空白文字を読み込んでプッシュバックするまでは満足できません。したがって、 'x'を入力して戻ることができますが、スペースやタブ以外を入力するまで、 'scanf("%c "、&c)'は返されません。 –