1. ホーム
  2. c++

[解決済み] c++ getline() が複数回呼ばれたときに、コンソールからの入力を待たない。

2022-02-13 14:09:02

質問

コンソールから、2つの文字列、2つのint、1つのdoubleという、いくつかのユーザー入力パラメータを取得しようとしています。私が使おうとしている関連するコードは、以下の通りです。

#include <string>
#include <iostream>
using namespace std;

// ...

string inputString;
unsigned int inputUInt;
double inputDouble;

// ...

cout << "Title: "; 
getline(cin, inputString);
tempDVD.setTitle(inputString);

cout << "Category: "; 
getline(cin, inputString);
tempDVD.setCategory(inputString);

cout << "Duration (minutes): "; 
cin >> inputUInt; 
tempDVD.setDuration(inputUInt);

cout << "Year: "; 
cin >> inputUInt; 
tempDVD.setYear(inputUInt);

cout << "Price: $"; 
cin >> inputDouble; 
tempDVD.setPrice(inputDouble);

しかし、プログラムを実行すると、最初の inputString の入力を待つのではなく、2回目の getline() の呼び出しまでコードが止まりません。したがって、コンソール出力は次のようになります。

タイトル カテゴリ

で、categoryの後にカーソルが表示されます。今入力すると、年入力にジャンプしてしまい、複数の文字列を入力することができません。何が起こっているのでしょうか?

解決方法は?

getline()の呼び出しと演算子 >>の使用が混在していることが問題です。

演算子 >>は、先頭の空白を無視するので、行の境界を越えて正しく続行することを覚えておいてください。しかし、入力の取得に成功した後は読み込みを停止するため、末尾の '\n' 文字を飲み込むことはありません。したがって、>> の後に getline() を使用すると、(読み込まれなかった '\n' 文字を最初に削除する) 注意を払わないと、通常は間違った結果を得ることになります。

コツは、両方の入力を使わないことです。適切な方を選んで、それに徹することです。

もし、すべて数字(または、operator >>と相性の良いオブジェクト)なら、operator >>を使ってください(文字列は、入出力と対称でない(つまり相性の良くない)唯一の基本型であることに注意してください)。

入力に文字列や、getline()を必要とするような組み合わせが含まれている場合は、getline()のみを使用し、文字列から数字をパースしてください。

std::getline(std::cin, line);
std::stringstream  linestream(line);

int  value;
linestream >> value;

// Or if you have boost:
std::getline(std::cin, line);
int  value = boost::lexical_cast<int>(line);