[解決済み] cinの後にgetline(cin, s)を使用する [重複].
質問
次のようなプログラムで、ユーザー入力の全行を文字列名にする必要があります。
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
を使用すると
cin >> number
コマンドの前に
getline()
というコマンドがありますが、(これが問題なのでしょうが)名前を入力することができません。 なぜでしょうか?
というようなことを聞いたことがあります。
cin.clear()
しかし、これがどのように機能するのか、なぜこれが必要なのか、まったくわかりません。
どのように解決するのですか?
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
上のコードでは、このビットが...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...番号の後の入力行の残りは空白のみであることを確認する。
無視を使えばいいのでは?
これではかなり冗長なので
ignore
の後のストリームで
>> x
は、次の改行までのコンテンツを破棄するためによく推奨される代替方法ですが、ホワイトスペース以外のコンテンツを破棄し、そうすることでファイル内の破損したデータを見落としてしまう危険性があります。 ファイルの内容が信頼できるかどうか、破損したデータの処理を避けることがどれほど重要かなどに応じて、気にしたりしなかったりすることができます。
では、どのような場合にクリアと無視を使うのでしょうか?
だから
std::cin.clear()
(そして
std::cin.ignore()
) は必要ありませんが、エラー状態を解除するのに便利です。 例えば、ユーザーが有効な数字を入力するチャンスを何度も与えたい場合などです。
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
skipwsなどでもっとシンプルにできないのか?
もう一つのシンプルだが中途半端な代替案として
ignore
を使用することです。
std::skipws
を使えば、行を読む前にいくらでも空白を飛ばすことができます...。
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...しかし、もし "1E6" のような入力(例えば、ある科学者が 1,000,000 を入力しようとしたが、C++ は浮動小数点数に対してこの記法をサポートしているだけ)があった場合、それを受け付けないため、結局は
number
に設定します。
1
であり、かつ
E6
の最初の値として読み取ります。
name
. これとは別に、有効な数字の後に1行以上の空白行があった場合、それらの行は黙って無視されます。
関連
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】デバッグアサーションに失敗しました