为什么std :: getline()在格式化提取后会跳过输入?

时间:2014-02-05 02:01:26

标签: c++ input iostream istream c++-faq

我有以下代码提示用户输入他们的姓名和状态:

#include <iostream>
#include <string>

int main()
{
    std::string name;
    std::string state;

    if (std::cin >> name && std::getline(std::cin, state))
    {
        std::cout << "Your name is " << name << " and you live in " << state;
    }
}

我发现该名称已成功提取,但不是州。这是输入和结果输出:

Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in "

为什么输出中省略了状态名称?我给出了正确的输入,但代码忽略了它。为什么会这样?

3 个答案:

答案 0 :(得分:10)

如果您按以下方式更改初始代码,一切都会好的:

if ((cin >> name).get() && std::getline(cin, state))

答案 1 :(得分:1)

既然上面的每个人都回答了输入 10\nMr Whisker\n 的问题,我想回答一个不同的方法。上面的所有解决方案都发布了缓冲区是否类似于 10\nMr Whisker\n 的代码。但是如果我们不知道用户将如何提供输入怎么办。用户可能会错误地输入 10\n\nMr. Whisker\n10 \n\n Mr. whisker\n。在这种情况下,上面的代码可能不起作用。所以,我使用下面的函数来获取字符串输入来解决这个问题。

string StringInput()  //returns null-terminated string
{
    string input;
    getline(cin, input);
    while(input.length()==0)//keep taking input until valid string is taken
    {
        getline(cin, input);
    }
    return input.c_str();
}

所以,答案是:

#include <iostream>
#include <string>

int main()
{
    int age;
    std::string name;

    std::cin >> age;
    name = StringInput();
    
    std::cout << "My cat is " << age << " years old and their name is " << name << std::endl;
    
}

额外:

如果用户输入a \n10\n \nmr. whiskey; 要检查 int 输入是否有效,可以使用此函数检查 int 输入(如果将 char 作为输入而不是 int 作为输入,程序将具有未定义的行为):


//instead of "std::cin>>age;" use "get_untill_int(&age);" in main function.
void get_Untill_Int(int* pInput)//keep taking input untill input is `int or float`
{
    cin>> *pInput;
    /*-----------check input validation----------------*/
    while (!cin) 
    {
        cin.clear();
        cin.ignore(100, '\n');
        cout<<"Invalid Input Type.\nEnter again: ";
        cin >>*pInput;
    }
    /*-----------checked input validation-------------*/
}

答案 2 :(得分:0)

这是因为隐式换行也称为换行符\n附加到终端的所有用户输入,因为它告诉流开始换行。在检查多行用户输入时,您可以使用std::getline安全地解决此问题。 std::getline的默认行为将读取输入流对象中的所有内容,包括换行符\n,在这种情况下为std::cin

#include <iostream>
#include <string>

int main()
{
    std::string name;
    std::string state;

    if (std::getline(std::cin, name) && std::getline(std::cin, state))
    {
        std::cout << "Your name is " << name << " and you live in " << state;
    }
    return 0;
}
Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in New Hampshire"