C++の標準入力


簡単な問題から話す
昨日問題を作ったとき、入力がありました.
3 4
aaaa aaaa aaaa
bbbbbbb bbbb
ccc cccccccc
^D

最初の行には、次の文の数と別の整数(ここでは役に立たないが、次の状況を説明するために使用される)を表す整数nが入力され、次はn文であり、各文は車に戻って終了する.私の考えは
int ij;
cin >> i >> j;
while(i--){
 string s;
 getline(cin, s);
}

しかし、結果的に私が初めてgetlineを呼び出して「」(空の文字列)を返しました.これはなぜですか.
なぜならcinにはバッファがあり、標準入力で車に戻った後、入力をバッファに入れ、cinはバッファで読み始めます.cinの>>オペレータは、デフォルトではスペース、タブを区切りとして使用します.3 4を入力して改行した後、入力バッファが読み取った内容は3 4
で、cin>>オペレータは3 4を読み取ってi,jに割り当て、バッファの中に
が残っていて、次のgetlineが読み取ったときに空の文字列を返します.
一つの解決方法はcin.get()は、バッファの
文字を吸収します.
int ij;
cin >> i >> j;
cin.get();
while(i--){
 string s;
 getline(cin, s);
}

実は、cin>>オペレータはスペース、タブ、リターンを区切りとして、コードcin >> i >>j;に対して、私はこのように入力したと思っていました.
2
3

このようにi,jが読んだのも2,3なのでcin>>も帰りを区切り文字にできると思います.今日私は資料を調べてやっと発見して、cin>>jの時、バッファの中には
3
があって、ただそれがjのために値を与える時
を無視しただけです.
cinの状態
この問題の原因を探していたとき、私はもっと面白いことに気づいた.
cin.clear()
int a;
char  b;
int ret = 0;
cout << "input a:" << endl;
cin >> a;
cout << "a:" << a << endl;
cout << "input b:" << endl;
cin >> b;
cout << "b:" << b << endl;

この行のコードは、数字ではなく文字を入力すると、デッドサイクルになります.最初にaに値を付与したとき、値を付与に失敗したので、cinは自分にステータスiostate state = badbitを設定します.これはcinが正常に動作しないことを招き、cin>>bも正常に動作しません.次は私の入力です.
➜  stl git:(master) ✗ g++ input.cpp -o input
➜  stl git:(master) ✗ ./input
input a:
asdf
a:0
input b:
b:

ここで私はaに文字を割り当てて、それからcin>>bは直接帰って、更にbを入力する機会を与えていないで、bに正しく値を割り当てることができません.
int a;
char  b;
int ret = 0;
cout << "input a:" << endl;
cin >> a;
cout << "a:" << a << endl;
cin.clear();  //     
cout << "input b:" << endl;
cin >> b;
cout << "b:" << b << endl;

cinエラーの後、ステータスをiostate state = goodbitに戻し、bがバッファから以前の入力を読み取ることができます.マイ入力
➜  stl git:(master) ✗ g++ input.cpp -o input
➜  stl git:(master) ✗ ./input
input a:
asdf
a:0
input b:
b:a      

cin.ignore() and cin.sync()
ネット上では、この2つの文は入力バッファを空にするために使われていると言われています.つまり、私が最初に話した問題に戻って、私は数字を入力してから車に戻り、
は入力バッファの最初に保存されています.では、私はこの2つの文を通じて入力バッファを空にして、他の入力を読み取ることができます.
cin.ignore()は、入力バッファを破棄する文字であり、istream& ignore (streamsize n = 1, int delim = EOF);であり、n文字を破棄したり、delimで終わる文字に破棄したりすることもできる.これは、推奨されるバッファをクリアする方法です.
cin.sync()という実際の機能は具体的な実装に依存し,私はg++でこの関数を使用しても役に立たないが,後で以下の文章で原因を見た.この文章はcinについて話した.sync()の具体的な機能は実現に依存し、VC++はcin.sync()は既存のバッファをクリアするために実現され、g++は何もしない.