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

C/C++で入力バッファをクリアする方法(fflush(stdin)の使い方と注意点)

C言語やC++でプログラムを作成していると、scanf()などによる標準入力の後に、入力バッファに残った余分なデータ(改行文字や未読み取りの文字)が原因で、意図しない動作が発生することがあります。このような場合に入力バッファをクリアする手段として、fflush(stdin)が使われることがあります。

本来fflush()関数は、出力ストリームのバッファをフラッシュ(強制的に書き出す)するための関数ですが、一部のコンパイラ環境ではscanf()の直後に使用することで、入力バッファもクリアできるよう拡張されています。

fflush()は成功した場合は0を返し、失敗した場合はEOFを返してエラー指示子(feof)がセットされます。

fflush(stdin) の構文

int fflush(FILE *stream);

サンプルコード

以下は、C言語でfflush(stdin)を使って入力バッファをクリアする例です。

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

int main() {
    char s[20];

    printf("文字列を入力してください : \n");
    scanf("%s", s);
    printf("入力された文字列 : %s\n", s);

    fflush(stdin);
    return 0;
}

実行結果

文字列を入力してください :
helloworld
入力された文字列 : helloworld

fflush(stdin) を使う際の注意点

fflush(stdin)はC言語の標準規格では未定義動作(undefined behavior)とされています。標準規格上、fflush()は入力ストリームに対する動作が定義されていないため、gcc(Linux)などの一部の環境では期待通りに動作しない可能性があります。Visual Studio(MSVC)などでは独自拡張として入力バッファのクリアがサポートされています。

より安全な代替手法

移植性の高いコードを書くためには、以下のような方法で入力バッファをクリアするのが推奨されます。

// 標準的な入力バッファクリアの方法
int c;
while ((c = getchar()) != '\n' && c != EOF);

このループは、改行文字またはファイル終端(EOF)に到達するまでバッファ内の残りの文字を読み捨てることで、確実かつ移植性のある形で入力バッファを空にします。

まとめ

  • fflush(stdin)は一部の環境では入力バッファをクリアできるが、標準規格では未定義動作である。
  • 移植性を重視するならgetchar()を使ったループ処理でバッファをクリアするのが安全。
  • 開発環境ごとの挙動の違いを理解した上で使用することが重要。
  1. C/C++で実装するバークレーアルゴリズム――分散システムの時刻同期を徹底解説

    バークレーアルゴリズムとは バークレーアルゴリズム(Berkeleys Algorithm)は、分散システムにおいて各ノードの時計を同期させるために用いられるアルゴリズムです。特に、以下のような状況にあるシステムで有効とされています。 マシンに正確な時刻源が存在しない場合 ネットワークやマシンにUTCサーバーが用意されていない場合 分散システムとは、物理的に離れた場所に配置された複数のノードが、ネットワークを介して相互に接続されたシステムのことを指します。各ノードの時計は独立して動作しているため、誤差が生じやすく、何らかの同期機構が必要になります。 バークレーアルゴリズムの仕組み このア

  2. C++で解くTwo Sum IV ― 二分探索木(BST)が入力の場合

    問題概要 二分探索木(BST)とターゲット値が1つ与えられます。このとき、BST内に「2つの要素の和がターゲット値と等しくなる」ような組み合わせが存在するかどうかを判定するのが本問題です。 例えば、次のような木が入力として与えられた場合を考えてみましょう。 この場合、出力は True(真)となります。 解法のアプローチ この問題は、BSTを中間順(inorder)走査して昇順の配列を作り、その後「双方向ポインタ(two pointer)」を使うことで効率的に解けます。具体的には、以下の手順に従います。 値を格納するための配列 v を定義します。 関数 inorder() を定義します(引