文字列を入力しようとしています。のようなものを入力するとうまくいきますJohn
。
しかし、次のようなものを入力するJohn Smite
と、エンドレス ループになって端末がクラッシュします。
string fullname;
do{
cout << "Please input the Full Name of the user: ";
cin >> fullname;
}while(fullname=="");
文字列を入力しようとしています。のようなものを入力するとうまくいきますJohn
。
しかし、次のようなものを入力するJohn Smite
と、エンドレス ループになって端末がクラッシュします。
string fullname;
do{
cout << "Please input the Full Name of the user: ";
cin >> fullname;
}while(fullname=="");
スペースはシンを投げ捨てています。getline を使用する必要があります。
これを試すことができます:
do{
cout << "Please input the Full Name of the user: ";
cin >> fullname;
}
while(fullname.length() == 0);
無限ループが発生する理由については、operator>>
オーバーロード forstd::string
は最初に先頭の空白を破棄してから、次の空白または使用可能な入力の終わりまで読み取ります。
「John Smite」と入力すると、最初の反復では「John」が読み取られ、2 回目の反復では「Smite」が読み取られ、その後の反復では入力がなくなります。fullname
問題は、読み取りを試みる前に実装がクリアされているように見えることです。しかし、ストリームはもはや良好な状態ではないため、これ以上の読み取りは不可能であり、無限ループが発生します。
代わりに次のようなことができます。
string temp;
string fullname;
do {
cin.clear(); // clear any error flags
do {
if (cin >> temp) fullname += temp + ' ';
} while (cin.good());
} while (fullname.empty());
これには、複数の隣接する空白文字を折りたたむという (良い) 副作用がありますが、それでもかなり扱いにくいです。
はるかに良い方法は、ただ言うことです
do std::getline(std::cin, fullname); while (fullname.empty());