getline不要求输入?

时间:2011-07-10 18:03:31

标签: c++ getline cin

这可能是一个非常简单的问题,但请原谅我,因为我是新人。 这是我的代码:

#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”。这是为什么?

3 个答案:

答案 0 :(得分:12)

operator>>getline混合时必须小心。问题是,当您使用operator>>时,用户输入他们的数据,然后按下回车键,将换行符放入输入缓冲区。由于operator>>是以空格分隔的,因此换行符不会放入变量中,而是保留在输入缓冲区中。然后,当你致电getline时,换行符就是它唯一要找的东西。因为这是缓冲区中的第一件事,它会立即找到它正在寻找的内容,而不需要提示用户。

修正: 如果您在使用getline后打算调用operator>>,请在中间调用ignore,或者执行其他操作以删除该换行符,也许是对getline的虚拟调用。< / p>

另一个选项,就像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;
    */
}

您可以为浮点数,双打和其他内容创建类似的功能。然后当你需要在int中,而不是这个:

cin >> i;

你这样做:

i = getInt(cin);

答案 1 :(得分:2)

这是因为你在前一个电话的输入流上留下了'\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";
}

答案 2 :(得分:2)

忽略某些字符,直到换行。

cin.ignore(256, '\n')
getline (cin,mystr);