web-dev-qa-db-ja.com

フォーマット文字列の最後に改行があるのに、scanfが入力を2回要求するのはなぜですか?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *method1(void)
{
    static char a[4];
    scanf("%s\n", a);
    return a;
}

int main(void)
{
    char *h = method1();
    printf("%s\n", h);
    return 0;
}

上記のコードを実行すると、プロンプトが入力を求めてきますtwice(コードでscanfを1回だけ使用します)。何故ですか?

(「jo」と入力しました。さらに入力を求められたので、もう一度「jo」と入力しました。その後、「jo」を1回だけ出力しました。)

17
joy

私のscanfマニュアルページから

フォーマット文字列の空白(空白、タブ、改行など)は、入力の空白(なしを含む)の任意の量と一致します。他のすべてはそれ自体にのみ一致します。

したがって、scanf ("%s\n", a)を使用すると、文字列とそれに続くオプションの空白がスキャンされます。最初の改行の後にさらに空白が続く可能性があるため、scanfは最初の改行の後に実行されず、次の行を探します。改行(またはタブやスペース)をいくつでも入力でき、scanfはそれ以上待機することに気付くでしょう。

ただし、2番目の文字列を入力すると、空白のシーケンスが区切られ、スキャンが停止します。

末尾の空白をスキャンしない場合は、scanf ("%s", a)を使用します。

20
Jens

scanfの文字列形式から\nを削除する必要があります。そのはず

scanf("%s",a);

編集:説明

%sは、scanfが入力文字を読み取り、区切り文字を取得することを意味します。区切り文字は、スペースやタブ、改行などの空白(\n)である必要があるため、最初の入力は、の区切り文字として取得されます。 "%s"および"\n"を文字列形式"%s\n"に追加すると、scanfは2つの改行を待機します。最初の改行は"%s"の区切り文字に関連し、2番目の改行は文字列形式の\nに関連します。

9
MOHAMED

上記の問題を回避するには、次のいずれかを使用できます:scanf("%s",a);またはscanf("\n%s",a);

0

Scanfstdio関数でエスケープシーケンスを使用しないでください

     scanf ("%s", a);
0
Vijay S B

削除する \n scanf形式から入力を指定すると、指定された出力に基づいて出力が1回表示されます。

0
kiranmai

代わりにgets()またはfgets()を使用してください...あるいはscanf( "%[^\n] s"、a);を使用してください。

0
Darshan Shah