5

これはおそらく非常に単純な問題ですが、初心者なのでご容赦ください。これが私のコードです:

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

int main ()
{ 
   string name;
   int i;
   string mystr;
   float price = 0;

   cout << "Hello World!" << endl;
   cout << "What is your name? ";
   cin >> name;
   cout << "Hello " << name << endl;
   cout << "How old are you? ";
   cin >> i;
   cout << "Wow " << i << endl;

   cout << "How much is that jacket? ";
   getline (cin,mystr);
   stringstream(mystr) >> price;
   cout << price << endl;
   system("pause");

   return 0;
}

問題は、how much is that jacket?getline が要求されたときに、ユーザーに入力を求めず、初期値の "0" を入力するだけであるということです。どうしてこれなの?

4

3 に答える 3

13

operator>>との混泳には注意が必要getlineです。問題は、 を使用する場合operator>>、ユーザーがデータを入力してから Enter キーを押すと、改行文字が入力バッファーに入れられることです。は空白で区切られているためoperator>>、改行文字は変数に入れられず、入力バッファーに残ります。次に、 を呼び出すgetlineと、検索対象は改行文字だけになります。これはバッファ内の最初のものであるため、探しているものをすぐに見つけ、ユーザーにプロンプ​​トを表示する必要はありません。

修正:getlineを使用した後に呼び出す場合operator>>は、その間に ignore を呼び出すか、改行文字を取り除くために何か他のことを行います。おそらく へのダミー呼び出しgetlineです。

もう 1 つのオプションは、Martin が話していたことに沿ったものですが、 をまったく使用せずoperator>>、 のみを使用してgetlineから、文字列を必要なデータ型に変換することです。これには、コードをより安全で堅牢にするという副作用があります。最初に次のような関数を書きます。

int getInt(std::istream & is)
{
    std::string input;
    std::getline(is,input);

    // C++11 version
    return stoi(input); // throws on failure

    // C++98 version
    /*
    std::istringstream iss(input);
    int i;
    if (!(iss >> i)) {
        // handle error somehow
    }
    return i;
    */
}

float、double、その他のものに対して同様の関数を作成できます。次に、これの代わりに int が必要な場合:

cin >> i;

これをして:

i = getInt(cin);
于 2011-07-10T18:09:01.910 に答える
3

'\n'これは、前の呼び出しからの入力ストリームに残っているためです。

cin >> i;  // This reads the number but the '\n' you hit after the number
           // is still on the input.

インタラクティブなユーザー入力を行う最も簡単な方法は、各行が個別に処理されるようにすることです (ユーザーは各プロンプトの後に Enter キーを押すため)。

その結果、常に行を読み取り、その行を処理します (ストリームに慣れるまで)。

std::string  line;
std::getline(std::cin, line);

std::stringstream linestream(line);

// Now processes linestream.
std::string garbage;
lienstream >> i >> garbage; // You may want to check for garbage after the number.

if (!garbage.empty())
{
    std::cout << "Error\n";
}
于 2011-07-10T18:08:09.303 に答える
2

改行に達するまで一部の文字を無視します。

cin.ignore(256, '\n')
getline (cin,mystr);
于 2011-07-10T18:14:56.823 に答える