CではC


61

に単一文字のためのscanfを行う方法:私はscanfで、ユーザから文字を取得しようとしていると私はそれを実行すると、ユーザーが何かを入力するためのプログラムは...

待っていない

これはコードです:

char ch; 
printf("Enter one char"); 
scanf("%c", &ch); 
printf("%c\n",ch); 

はなぜ動作しませんか?

  0

ただ、Cプログラムが含まれている場合は、ここで明確にする*のみ*上記のコード、それが動作します。 1つのOPのような潜在的な問題は、P.Pの答えに述べられている理由により、他のI/Oコードと一緒に使用される場合にのみ発生します。 04 1月. 182018-01-04 11:00:44

169

浮遊改行が入力ストリームにありますので、もし%c変換指定子は、自動的に(例えば、前のエントリから)、任意の先頭の空白をスキップしませんscanf呼び出しはすぐにそれを消費します。書式文字列内の空白は先頭の空白をスキップするscanfを伝え

scanf(" %c", &c); 

、および最初の非空白文字:問題の周り

一つの方法は、書式文字列内の変換指定の前に空白を置くことです文字は%c変換指定子で読み取られます。


1

scanfの前にバッファをクリアするためにfflush(stdin);を入れます。

+8

'fflush(stdin);'はC標準に準拠しない動作*です。 02 12月. 162016-12-02 19:05:55

  0

これは間違っています、 'fflush(stdin)'はUBです。 19 1月. 182018-01-19 09:17:41


0

コンパイラが空白を無視するように%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; 
} 
+14

これはジョン・ボードが2年前に与えたのと同じ提案です。 11 10月. 142014-10-11 15:20:45


-4

私にとってはこのスーツ:

#include <stdio.h> 
    int main (void) 
    { 
     char a; 
     scanf ("%c", &a); 
     printf ("%c\n", a); 
    return 0; 
    } 

あなたのコードは作品ではない理由を知ってはいけません。 「scanf関数」:あなたは、Visual Studio上で作業している間、私はあなたのようなエラーが出る可能性が

、GCCここ


1

私は共有したい似事があるとCodeliteを使用する関数や変数は安全でない可能性があります。代わりにscanf_sの使用を検討してください。

char c; 
scanf_s("%c", &c, 1); 

非ヌルのために複数の文字が終了すると:、非推奨を無効にするこれを防ぐために_CRT_SECURE_NO_WARNINGS

を使用するには、次のように単一の文字を読み取ることができる次の形式

でそれを書く必要があります文字列が読み込まれると、整数が幅指定とバッファサイズとして使用されます。

char c[4]; 
scanf_s("%4c", &c, _countof(c)); 

よろしく、


-2

使用文字列の代わりに、

char c[10]; 
scanf ("%s", c); 

ようchar 私はそれは素敵な作品信じて。

+3

これは質問に答えることができません。なぜなら、OPは一連の文字ではなく、単一の文字_を 'scanf &apos;したいからです。 22 6月. 162016-06-22 16:59:11


6

まず、scanf()を避けてください。それを使うことは痛みに値するものではありません。

参照:Why does everyone say not to use scanf? What should I use instead?

は、入力ストリームに残さ空白文字の任意の数を無視し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; 
} 

()先頭の空白を使って同じように固定することができ、それは常に上記のように、その簡単なことはないだろう。 もう1つの大きな問題は、scanf()は、入力ストリームの入力がフォーマットと一致しない場合、その入力を破棄しないことです。たとえば、と入力した場合、scanf("%d", &int_var);のように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; 
} 

を別の一般的な問題は、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; 
} 

fgets()への呼び出しを以前のscanf()の呼び出しによって残された改行を読み、関数fgets()は改行に遭遇したときに入力が読んで終了しているため、入力を待ちません。

scanf()に関連する他の多くの同様の問題があります。そのため、一般的には避けることをお勧めします。

代替手段はありますか?単一の文字を読み取るために、次の方法で代わりにfgets()機能を使用してください:

#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; 
} 

一つのディテールをがinutバッファに十分なスペースがあるかどう改行文字で読みますfgets()を使用する際に注意します。それが望ましくない場合は、それを削除することができます:

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 */

1

getcharを使用してみてください。代わりに

構文:予想通り

void main() { 
    char ch; 
    ch = getchar(); 
}