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

Coc*_*ola 6 c++

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

Please enter your selection
Please enter your selection
Run Code Online (Sandbox Code Playgroud)

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

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.
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢

pax*_*blo 10

当您进入循环时,可能还存在来自先前操作的输入缓冲区中的某些内容.

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


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

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

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

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

如果这种情况,例如:

cin.ignore(INT_MAX, '\n');
Run Code Online (Sandbox Code Playgroud)

在循环之前可以修复它.

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


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

#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;
}
Run Code Online (Sandbox Code Playgroud)

连同成绩单:

Prompt 1: Hello
char [H]
Prompt 2: str1 [ello]
Prompt 3: from Pax
str2 [from Pax]
Run Code Online (Sandbox Code Playgroud)

在其中你可以看到,它实际上并没有坐等新的输入提示2,它只是让你在提示1进行的其余部分,因为字符e,l,l,o\n仍然在输入缓冲区.

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

Prompt 1: Hello
char [H]
Prompt 2: from Pax
str1 [from Pax]
Prompt 3: Goodbye
str2 [Goodbye]
Run Code Online (Sandbox Code Playgroud)