私は次のプログラムを持っています:
_int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d",&a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c",&c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
_
Cの本を読むと、著者はscanf()
がバッファに改行文字を残したと言っているため、プログラムはユーザーがデータを入力するために4行目で停止せず、新しいc2の行文字。5行目に移動します。
そうですか?
ただし、これはchar
データ型でのみ発生しますか?行1、2、3のようにint
データ型でこの問題は見られなかったので、正しいですか?
scanf()
関数は、文字以外の変換を解析する前に空白を自動的に削除します。文字フォーマット(主に_%c
_。スキャンセット_%[…]
_ —および_%n
_)も例外です。空白は削除されません。
オプションの空白をスキップするには、_" %c"
_を先頭に空白を付けて使用します。 scanf()
形式の文字列には末尾の空白を使用しないでください。
これは、入力ストリームに残っている末尾の空白を行末までも消費しないため、 getchar()
または-を使用する場合にも注意してください。 fgets()
同じ入力ストリーム。 _%d
_やその他の文字以外の変換の場合と同様に、scanfに空白before変換をスキップさせるだけです。
空白以外の「ディレクティブ」( POSIX scanf用語 を使用する)は、scanf("order = %d", &order);
のリテラルテキストのように、変換以外にも空白をスキップしないことに注意してください。リテラルorder
は、次に読み込む文字と一致する必要があります。
したがって、前の行から改行をスキップしたいが、固定文字列でのリテラルの一致が必要な場合は、おそらく_" order = %d"
_が必要です この質問のように 。
scanf(" %c", &c2);
を使用します。これで問題が解決します。
別のオプション( here から取得した)は、assignment-supression optionを使用して改行を読み取り、破棄することです。これを行うには、%
とc
の間にアスタリスクが付いた文字を読み取る形式を配置します。
scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3
scanf
は、次の文字(つまり、改行)を読み取りますが、ポインターには割り当てません。
しかし、最後に、私は2番目になります FAQの最後のオプション :
または、要件に応じて、scanf()/ getchar()を忘れて、fgets()を使用してユーザーからテキスト行を取得し、自分で解析することもできます。
2番目のgetchar()
を呼び出す前にscanf()
を使用します。
scanf("%c", &c1);
getchar(); // <== remove newline
scanf("%c", &c2);