C++ で入力バッファをクリアする

胡金庫 2023年10月12日
C++ で入力バッファをクリアする

この記事では、C++ で入力バッファをクリアする方法の複数の方法を示します。

C++ で std::cin::ignore 関数を使用して入力バッファをクリアする

ignorestd::cin オブジェクトの組み込み関数であり、指定された区切り文字まで入力ストリームから文字を抽出して破棄するために使用できます。cin::ignore 関数の動作について説明する前に、cin / cout としての標準入力ストリームと出力ストリームがバッファリングされることに注意してください。これは、ユーザーの書き込み/読み取りの間に何らかの簿記が行われることを意味します。オペレーティングシステムカーネルの実際のバッファ状態。このバッファは C++ ライブラリ自体によって管理され、その目的は読み取り/書き込み要求をより効率的にすることです。バイトごとにオペレーティングシステムサービスを呼び出すと、CPU リソースの使用が非常に非効率になるため、中間バッファーを使用していくつかの要求を蓄積し、単一の要求でオペレーティングシステムを呼び出すことに注意してください。

したがって、cin::ignore は、連続した呼び出しがあるときに誤って読み取られる可能性のあるバッファ内の残りのバイトを破棄する可能性があります。次のサンプルコードは、無視動作をより明確に示すように設計されています。cin ストリームから 3つの整数を読み取り、対応する変数に格納する無限の while ループを実装しました。整数は cout に出力され、次の反復でルーチンが実行されます。ユーザーが最初の反復で 3つ以上の整数を指定できることに注意してください。その場合、cin.ignore の前のコードはそのうちの 3つだけを格納し、他のコードは引き続き中間バッファーに存在します。ここで、指定されたパラメーターで cin.ignore が呼び出されない場合、次の反復 cin >> 行が残りの入力を読み取り、一貫性のない動作が発生します。このようなシナリオでは、cin.ignore 呼び出しを利用して、指定された文字が検出されなくなるまで入力を破棄できます。この場合、cin ストリームをバッファリングするために一般的に使用される改行文字を指定しました。

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  while (true) {
    int i1, i2, i3;
    cout << "Type space separated numbers: " << endl;
    cin >> i1 >> i2 >> i3;
    if (i1 == 0) exit(EXIT_SUCCESS);
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    cout << i1 << "; " << i2 << "; " << i3 << endl;
  }

  return EXIT_SUCCESS;
}

出力(サンプルユーザー入力を使用):

Type space separated numbers:
12 32 54
12; 32; 54

または、スペース文字の区切り文字で分割された 2つの文字列を受け取る別のサンプルコードを実装することもできます。このシナリオでは、ユーザーが 3つ以上の名前を指定すると、スペースで区切られた 2つの文字列の後にすべてのイニシャルが削除される可能性があります。ユーザー入力に名前とスペースが 1つしかない場合は、常に cin 入力を終了する改行文字が 2 番目のイニシャルとして格納されます。後者の動作は、<< name << surname ステートメントの後に 1 文字の出力を追加することで実証できます。

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  char name, surname;
  cout << "Type your name and surname: ";
  name = cin.get();
  cin.ignore(numeric_limits<std::streamsize>::max(), ' ');
  surname = cin.get();

  cout << "Your initials are: " << name << surname << endl;

  return EXIT_SUCCESS;
}

出力(サンプルユーザー入力を使用):

Type your name and surname: Lama Lime
Your initials are: LL
``
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ IO