Cでは:私はscanf
を使ってユーザーからcharを取得しようとしています、そしてそれを実行するとき、プログラムはユーザーが何かをタイプするのを待ちません...
これはコードです:
char ch;
printf("Enter one char");
scanf("%c", &ch);
printf("%c\n",ch);
なぜうまくいかないのですか?
%c
変換指定子は、先行する空白を自動的にスキップしません。そのため、(例えば、前のエントリからの)入力ストリームに不要な改行がある場合、scanf
呼び出しは直ちにそれを消費します。
問題を回避する1つの方法は、フォーマット文字列の変換指定子の前に空白を入れることです。
scanf(" %c", &c);
フォーマット文字列の空白は、先頭の空白をスキップするようにscanf
に指示し、最初の空白以外の文字は%c
変換指定子で読み込まれます。
まず第一に、scanf()
を避けてください。それを使用することは痛みの価値がありません。
参照してください: なぜ誰もがscanfを使用しないと言うのですか?代わりに何を使うべきですか?
scanf()
で空白文字を使用しても、入力ストリームに残っている空白文字はいくつでも無視されます。もっと多くの入力を読む必要がある場合はどうしますか?検討してください:
#include <stdio.h>
int main(void)
{
char ch1, ch2;
scanf("%c", &ch1); /* Leaves the newline in the input */
scanf(" %c", &ch2); /* The leading whitespace ensures it's the
previous newline is ignored */
printf("ch1: %c, ch2: %c\n", ch1, ch2);
/* All good so far */
char ch3;
scanf("%c", &ch3); /* Doesn't read input due to the same problem */
printf("ch3: %c\n", ch3);
return 0;
}
3番目のscanf()は、先頭の空白を使って同じ方法で修正できますが、上記のように単純になるわけではありません。もう1つの大きな問題は、scanf()
がフォーマットと一致しない場合、入力ストリーム内の入力を破棄しないことです。たとえば、scanf("%d", &int_var);
のようにabc
にint
を入力した場合、abc
を読み取って破棄する必要があります。検討してください:
#include <stdio.h>
int main(void)
{
int i;
while(1) {
if (scanf("%d", &i) != 1) { /* Input "abc" */
printf("Invalid input. Try again\n");
} else {
break;
}
}
printf("Int read: %d\n", i);
return 0;
}
もう1つの一般的な問題はscanf()
とfgets()
の混在です。検討してください:
#include <stdio.h>
int main(void)
{
int age;
char name[256];
printf("Input your age:");
scanf("%d", &age); /* Input 10 */
printf("Input your full name [firstname lastname]");
fgets(name, sizeof name, stdin); /* Doesn't read! */
return 0;
}
前のscanf()呼び出しによって残された改行が読み取られ、改行に遭遇するとfgets()が入力読み取りを終了するため、fgets()
の呼び出しは入力を待ちません。
scanf()
に関連する他の多くの同様の問題があります。それはそれを避けることが一般的に推奨される理由です。
だから、代替は何ですか?単一文字を読み取るには、代わりに fgets()
functionを次のように使用します。
#include <stdio.h>
int main(void)
{
char line[256];
char ch;
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
return 0;
}
fgets()
を使用する際に注意すべき1つの詳細は、inutバッファーに十分なスペースがある場合、改行文字で読み込まれます。それが望ましくないなら、あなたはそれを削除することができます:
char line[256];
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */
fgetsもgetcharも、この問題を解決するためには機能しません。唯一の回避策は、scanf scanf( "%c"、ch)を使用している間、%cの前にスペースを空けることです。 //動作します
次のような喧嘩でも動作しません..
char line[256];
char ch;
int i;
printf("Enter a num : ");
scanf("%d",&i);
printf("Enter a char : ");
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
これは私のためにうまくいく
int main(){
char c;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
Scanfの前にfflush(stdin);
をバッファをクリアするために置きます。
これは私が共有したいと思う似たようなことです、
visual Studioで作業している間、次のようなエラーが発生する可能性があります。代わりにscanf_sを使用することを検討してください。廃止予定を無効にするには、_CRT_SECURE_NO_WARNINGSを使用します。
これを防ぐには、次の形式で書く必要があります。
単一文字は次のように読むことができます。
char c;
scanf_s("%c", &c, 1);
NULLでない終端文字列の複数の文字が読み取られる場合、整数が幅指定およびバッファサイズとして使用されます。
char c[4];
scanf_s("%4c", &c, _countof(c));
よろしく、
getchar()を使ってみてください。代わりに
構文:
void main() {
char ch;
ch = getchar();
}
有効な変数を使用する必要があります。 ch
は、このプログラムには無効な変数です。 char Aaa
を使用してください。
char aaa;
scanf("%c",&Aaa);
テストしてそれが機能します。
コンパイラが空白を無視するように、%c変換指定子の前にスペースを入れます。プログラムは以下のように書くことができます。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch;
printf("Enter one char");
scanf(" %c", &ch); /*Space is given before %c*/
printf("%c\n",ch);
return 0;
}