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>>,用户输入他们的数据,然后按下回车键,这会将换行符放入输入缓冲区。由于operator>>是空格分隔,换行符不会放入变量中,而是留在输入缓冲区中。然后,当您调用 时getline,换行符是它唯一要寻找的东西。由于这是缓冲区中的第一件事,它会立即找到它正在寻找的内容,并且永远不需要提示用户。

修复:如果您要getline在使用后operator>>调用,请在两者之间调用忽略,或者做其他事情来摆脱那个换行符,也许是对getline.

另一种选择,这与马丁所说的一致,是根本不使用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;
    */
}

你可以为浮点数、双精度数和其他东西创建一个类似的函数。然后当你需要 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.

进行交互式用户输入的最简单方法是确保独立处理每一行(因为用户将在每次提示后按回车键)。

结果总是读取一行,然后处理该行(直到您熟悉流)。

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 回答