Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語でscanf()の後にfgets()/gets()/scanf()が続く場合の問題と対処法

C言語では、scanf() の直後に fgets() / gets() / 別の scanf() を呼び出すと、意図どおりに入力を読み取れないことがあります。原因の多くは、前の入力操作で改行文字(\n)が標準入力バッファに残っていることにあります。本記事では、代表的な2つのケースについて、実際のコード例と実行結果をもとに挙動と対策を解説します。

fgets() / gets() の前に scanf() がある場合

サンプルコード

#include <stdio.h>

int main(void) {
    int x;
    char str[100];

    scanf("%d", &x);
    fgets(str, 100, stdin);

    printf("x = %d, str = %s", x, str);
    return 0;
}

実行結果

入力:
30
String

出力:
x = 30, str =

解説

fgets() と gets() は、実行時にユーザーから文字列を受け取るための関数です。ところが上記のコードでは、整数値を入力して Enter キーを押した瞬間、その改行文字がバッファに残ってしまいます。続く fgets() は、本来入力されるべき文字列「String」ではなく、この残った改行文字を先に入力として読み込んでしまうため、str には空の文字列が格納され、何も表示されません。

対策

scanf() で数値などを読んだ直後に getchar() を1回呼び出して改行を消費するか、while (getchar() != '\n'); でバッファを空にしてから fgets() を呼び出せば、意図した文字列を正しく読み取れます。

scanf() の後に別の scanf() がある場合

同じ種類の入力を繰り返し受け付ける場合、scanf() をループの中で連続して呼び出すことがよくあります。

サンプルコード

#include <stdio.h>

int main(void) {
    char a;
    printf("enter q to quit");
    do {
        printf("\nenter a character and q to exit");
        scanf("%c", &a);
        printf("%c\n", a);
    } while (a != 'q');
    return 0;
}

実行結果

入力(各文字の後にEnterキーを押す):
a
b
q

出力:
enter q to quit
enter a character and q to exita
a
enter a character and q to exit
enter a character and q to exitb
b
enter a character and q to exit
enter a character and q to exitq
q

解説

実行結果を見ると、プロンプト「enter a character and q to exit」が余分に表示されています。これは、scanf() が入力文字の後に残した改行文字(\n)を、次の scanf() が入力として読み込んでしまうためです。改行文字を読み込んだ周回では文字の出力がスキップされ、プロンプトだけが表示されてループが無駄に一回転してしまいます。

対策

  • 書式指定子の前に半角スペースを入れるscanf(" %c", &a); — 空白があると scanf() は改行などの空白文字を読み飛ばしてくれます(最も簡単で一般的な方法)。
  • getchar() を挟む:scanf() の直後に getchar() を1回呼び出し、残った改行文字を読み捨てます。
  • 書式に \n を含めるscanf("%c\n", &a); のように記述する方法もありますが、挙動が分かりにくいため、上記2つの方法が推奨されます。

このように、scanf() と他の入力関数を組み合わせて使う際は、バッファに残る改行文字の扱いに注意することが重要です。事前に改行を適切に処理しておけば、入力ミスによる予期しない動作を防げます。

  1. Windows 8のパスワードを忘れたときのリセット方法|画像・PIN・テキストパスワード完全ガイド

    Windows 8は、Microsoft史上最もセキュリティ性の高いOSとして、ログイン時に利用できる新しいパスワード方式を2つ導入しました。それが「4桁のPIN」と「ピクチャパスワード(画像パスワード)」です。PINを使えば素早くサインインでき、ピクチャパスワードなら写真をなぞるジェスチャで、より直感的かつ楽しくログインできます。とはいえ、従来のテキストパスワードも依然として重要です。ピクチャパスワードやPINをリセットする際には、通常のパスワードが必要になる場面があるためです。 Windows 8のパスワードを忘れてしまった方もご安心ください。本記事では、テキストパスワード、ピクチャパスワ

  2. Windows・Mac・オンラインでGoogle Earthを録画する方法【完全ガイド】

    世界は思っているよりずっと小さいもの。なぜそう言えるのか、ご存じですか?世界中を旅することが夢なら、旅行チケットに何千円も何万円も費やす必要はないかもしれません。Google Earthのようなプラットフォームが、あなたの世界一周の憧れを叶えてくれるからです。場所を入力するだけで、その土地のバーチャルな絶景を楽しむことができます。もちろん、実際にその場所へ足を運ぶ体験には及びません。しかし、例えば近いうちに家族や友人と一緒に旅行に行く予定の場所を、事前にGoogle Earthでバーチャルツアーとして共有したいと思ったことはありませんか?そんなとき、Google Earthの動画はどうやって撮