我正在尝试使用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.
}
有人知道为什么会这样吗?
谢谢
答案 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)来检查原因。当你能找到真正的答案时,为什么要提出理论呢?