cin.getline not executing c++
cin.getline not executing c++
出于某种奇怪的原因,当我把它放在这个 else if 块中时,我的输入行cin.getline(oneLine, 80);
被完全忽略了。 我不明白为什么,因为当我将其移动到程序中的其他地方时,它可以工作。
else if (choice == "user-id")
{
cout << endl << "Enter a full name e.g. John Smith ";
char oneLine[80];
cin.getline(oneLine, 80);
cout << oneLine;
}
这是我代码的其余部分。 我是C++新手,所以我确信我的很多约定充其量可能是有问题的。
int main( )
{
while (true)
{
int pause;
string choice = "proceed";
string nameGiven;
string userIdGiven;
string result;
using namespace std ;
while ((choice != "name") && (choice != "user-id"))
{
cout << "Would you like to search for a name or user-id? ";
cin >> choice;
if ((choice != "name") && (choice != "user-id"))
cout <<"Please enter a valid choice (name or user-id)" << endl;
}
if (choice == "name")
{
string dataType = "int";
while (true)
{
cout << endl << "Enter a valid user id (4 digit maximum) ";
cin >> userIdGiven;
if (valid(userIdGiven))
break;
else
cout << endl << "Not a valid number. " << endl;
continue;
}
result = findData(userIdGiven, dataType);
cout << "name: " << result;
}
else if (choice == "user-id")
{
cout << endl << "Enter a full name e.g. John Smith ";
char oneLine[80];
std::getline(oneLine, 80);
cout << oneLine;
}
string ans;
cout << endl << "Would you like to play again? (yes/no) " << endl;
cin >> ans;
if ( (ans == "yes") || (ans == "Yes") || (ans == "Y") || (ans == "y") )
continue;
else
break;
cin >> pause;
}
return 0;
}
您的std::cin
对象在之前的输入操作中处于错误状态(std::cin.good() == false
(。例如,您可能尝试读取一个数字,但输入缓冲区中只有母数字字符。
在继续使用 std::istream
之前,请始终检查输入是否成功。
注意:
不要使用与char*
一起操作的旧输入函数,因为它们比在std::string
上运行的新输入函数更复杂且使用起来更不安全。在您的情况下,请使用 std::getline(std::istream&, std::string&, char = 'n')
.
twsaef的评论基本上是正确的......您正在将字符串流式传输到 Choice,这会消耗字符,直到但不包括下一个空格字符 - 您可能正在键入换行符来终止输入,因此它保留在缓冲区中。然后你使用 getline 看到该换行符并读取一个空字符串。
最简单的解决方案是调用getline()
来读取初始字符串,然后检查选择是"name"还是"user-id"。 更好的是 - 编写一个"trim"函数来在比较之前从行中删除空格(boost 字符串库已经有这个(。 否则,您可以使用读取和忽略std::cin
中的字符,直到得到""。 或者甚至读取一行然后放入字符串流并从那里读取字符串...... 很多选择。
并且,请检查您的流状态! 尝试使用:
if (std::cin >> x)
// x was parsed from stream... use it
else
// print an error so you know where things failed!
FWIW,在看到更新之前,我猜到了问题是什么(这很常见(,并对其他猜测笑了笑(尽管即使他们错过了 OP 的问题,他们也提出了非常好的观点(。
代码行工作正常,并且如广告所示。它不会碰巧按照您想要的方式工作。
当您从 std::cin 读取时,不会暂停程序并等待输入。导致暂停的原因是缺少足够的输入数据用于读取操作。
输入一次一行地馈送到程序。请记住,控制台窗口也是一个程序。它负责将用户的按键转换为文本字符(实际上是字节(,处理诸如退格键之类的事情,并将其全部收集成行。
假设你读了一篇带有operator>>
int
,然后用getline
阅读了一行。在用户点击 Return 键之前,程序不会看到int
,因为这会触发控制台向程序提供一行输入。
operator>>
将跳过前导空格,读取整数,并保留尾随空格。换行符为空格。输入中有一个换行符(显然在行尾(。
getline()
不会跳过任何前导空格,并一直读到下一个换行符。下一个字符恰好是换行符,所以getline()
愉快地阅读一个空行,程序继续。
那么如何解决这个问题呢?如果您正在读取来自cin
的所有输入,则有可能您希望程序在每次进行读取操作时暂停。做到这一点的方法是确保在这一点上永远不会有任何可用数据,而做到这一点的方法是每次阅读某些内容时都读取所有可用数据 - 即整行。
因此,请始终阅读cin
中的一整行。如 wilx 所述,请使用免费函数std::getline
。不要使用流的.getline
成员函数。使用 std::string
表示文本字符串。这就是它的目的。它会让你的生活更轻松。这也意味着,如果你期待一个整数并且用户输入"76长号",你可以摆脱"长号"数据(并且可以决定你是想把它扔掉,还是对用户大喊大叫,让他重新输入一个数字,没有任何有趣的评论(。
但那又如何?你只有一个字符串,你可能想要一个 int。幸运的是,有一个简单的解决方案。我们可以将字符串视为流数据源,使用标准库类 std::stringstream
.我们只是从字符串构造一个字符串流,然后像std::cin
一样使用它 - 即我们可以用 operator>>
从中读取,检查流状态以查看读取是否成功,等等。
正如 sbi 所指出的,始终检查读取是否成功!如果您尝试读取int
并且流包含诸如"嗨妈妈"之类的文本,那么 (a( int
变量不会被更改(因此,如果它未初始化,它仍然未初始化,这是一种非常危险的状态(,以及 (b( 流将进入"失败"状态,并且在您清除它之前不会再读取, (c(即使你清除了它,数据仍然会在那里,如果你不小心,这可能会触发无限循环。
幸运的是,有了 单独的stringstream
,我们避免了各种并发症。如果读取失败,那么所有这些事情都会发生在stringstream
对象上 - 而不是std::cin
.getline
操作将始终在std::cin
上成功,除非用户明确指示文件结尾(Linux 上的 control-D 字符或 Windows 上的 control-Z(。我们可以轻松检查stringstream
是否处于失败状态,循环并创建另一个 - 旧的将自动清理。
我们甚至可以创建一个辅助函数,例如:
template <typename T>
// Attempt to read into to_read, and return whether successful.
bool read_primitive_from_input(std::istream& input, T& to_read) {
std::string line;
std::getline(std::cin, line);
std::istringstream iss(line);
return iss >> to_read;
}
std::stringstream
由标准库标头<sstream>
提供。 当然,std::string
来自<string>
。