当我使用getline时,为什么cout打印两次?

时间:2012-08-10 01:19:01

标签: c++

我正在尝试使用getline读取一串文本。出于某种原因,它会打印两次“请输入你的选择”:

Please enter your selection
Please enter your selection

如果我键入无效文本,它会再次循环,并且此后每次循环只打印一次。

while (valid == false) {    
    cout << "Please enter your selection" << endl;
    getline (cin,selection);

    // I have a function here which checks if the string is valid and sets it to true 
    // if it is valid.  This function works fine, so I have not included it here.  The while
    // look breaks correctly if the user enters valid input.
}

有人知道为什么会这样吗?

谢谢

2 个答案:

答案 0 :(得分:10)

可能当你进入循环时,前一个操作的输入缓冲区中仍有一些东西。

getline拾取,发现无效,然后循环再次运行。


举例来说,让我们说,在你进入循环之前,你会读到一个字符。但是,在熟食模式下,您需要在操作之前输入字符换行符。

因此,您读取了该字符,并且换行符保留在输入缓冲区中。

然后你的循环开始,读取换行符,并认为它无效,然后循环返回以获得实际的输入行。

这是一种可能性,当然,可能还有其他可能性 - 它在很大程度上依赖于之前的代码循环及其对cin的作用。

如果 的情况如下:

cin.ignore(INT_MAX, '\n');
循环之前

可以修复它。

或者,您可能希望确保在任何地方都使用基于行的输入。


以下是一些代码,可以看到该方案的实际应用:

#include <iostream>
#include <climits>

int main(void) {
    char c;
    std::string s;

    std::cout << "Prompt 1: ";
    std::cin.get (c);
    std::cout << "char [" << c << "]\n";
    // std::cin.ignore (INT_MAX, '\n')

    std::cout << "Prompt 2: ";
    getline (std::cin, s);
    std::cout << "str1 [" << s << "]\n";

    std::cout << "Prompt 3: ";
    getline (std::cin, s);
    std::cout << "str2 [" << s << "]\n";

    return 0;
}

连同成绩单:

Prompt 1: Hello
char [H]
Prompt 2: str1 [ello]
Prompt 3: from Pax
str2 [from Pax]

你可以看到它实际上并没有等待提示2的新输入,它只是得到你在提示1输入的其余行,因为字符 e ,< kbd> l , l o \ n 仍然在输入缓冲区中。

当您取消注释ignore行时,它会以您期望的方式行事:

Prompt 1: Hello
char [H]
Prompt 2: from Pax
str1 [from Pax]
Prompt 3: Goodbye
str2 [Goodbye]

答案 1 :(得分:1)

我会使用调试器(例如linux中的gdb)来检查原因。当你能找到真正的答案时,为什么要提出理论呢?