出于一些奇怪的原因,当我把它放在其他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;
}
答案 0 :(得分:2)
您的std::cin
对象在之前的输入操作中处于错误状态(std::cin.good() == false
)。例如,您可能尝试读取数字,但输入缓冲区中只有非数字字符。
在继续使用std::istream
之前,请务必检查输入是否成功。
注意: 不要使用与char*
一起使用的旧输入函数,因为它们比新的操作更复杂且安全性更低在std::string
。在您的情况下,请使用std::getline(std::istream&, std::string&, char = '\n')
。
答案 1 :(得分:1)
twsaef的评论实质上是正确的...你正在将一个字符串串入选择,它会消耗字符直到但不包括下一个空白字符 - 你可能正在键入换行符来终止输入,所以它留在缓冲区中。然后你使用getline看到那个换行符并读取一个空字符串。
最简单的解决方案是调用getline()
来读取初始字符串,然后检查选项是“name \ n”还是“user-id \ n”。更好 - 编写一个“修剪”函数,以便在比较之前从行中删除空格(提升字符串库已经具有此功能)。否则,您可以使用std::cin
中的读取和忽略字符,直到获得'\ n'。或者甚至读一行然后放入一个字符串流并从那里读取一个字符串....很多选择。
并且,请检查您的流状态!尝试使用:
if (std::cin >> x)
// x was parsed from stream... use it
else
// print an error so you know where things failed!
答案 2 :(得分:0)
FWIW,我在看到更新之前猜到了问题是什么(这是愚蠢的常见),并在其他猜测中对自己轻笑(尽管即使他们错过了OP的问题他们也能提出非常好的观点)。
代码行正常工作并且正如所宣传的那样。它不会像你想要的那样工作。
当您从std :: cin读取时,不暂停程序并等待输入。导致暂停的原因是读操作缺少足够的输入数据。
输入一次一行地输入您的程序。请记住,控制台窗口也是一个程序。它负责将用户的按键转换为文本字符(真正的字节),处理退格键等内容,并将其全部收集到行中。
所以说你用int
读了一个operator>>
,然后用getline
读了一行。在用户点击Return键之前,程序将看不到int
,因为这会触发控制台向您的程序提供一行输入。
operator>>
将跳过前导空格,读取整数,单独留下尾随空格。换行符是空格。输入中有换行符(显然在行的末尾)。
getline()
不会跳过任何前导空格,直到下一个换行符为止。下一个字符恰好是换行符,因此getline()
愉快地读取一个空行,程序继续执行该操作。
那你怎么解决这个问题?如果您正在阅读cin
的所有输入,那么您希望程序在每次进行阅读操作时都会暂停。这样做的方法是确保在那时从来没有任何可用的数据,并且这样做的方法是在每次阅读时阅读所有可用的内容 - 即整行 -
所以,请务必阅读cin
的完整一行。 正如wilx所述,请使用免费功能std::getline
。不要使用流的.getline
成员函数。使用std::string
表示文本字符串。这就是它的用途。它会让你的生活更加轻松。这也意味着如果你期望一个整数并且用户键入“76长号”,你就可以摆脱“长号”数据(并且可以决定你是想把它扔掉,还是对用户大喊大叫,让他重新输入一个没有任何有趣评论的数字。)
但那又怎么样?你只需要一个字符串,你可能想要一个int。幸运的是,有一个简单的解决方案。我们可以使用标准库类std::stringstream
将字符串视为流数据源。我们只是从字符串构造一个字符串流,然后像std::cin
一样使用它 - 即我们可以用operator>>
读取它,检查流状态以查看读取是否成功等等。
如sbi所述,请务必检查阅读是否成功!如果您尝试阅读int
并且流中包含“hi mom”等文字,则(a){{ 1}}变量将不被更改(因此,如果它未被初始化,它仍未被初始化,这是一个非常危险的状态),并且(b)流将进入“失败”状态,将不读取,直到你清除它,并且(c)即使你清除它,数据仍将存在,如果你不小心可能会触发无限循环。
幸运的是,通过单独的int
,我们可以避免各种并发症。如果阅读失败,那么所有这些事情都发生在stringstream
对象上 - 而不是stringstream
。 std::cin
操作将始终在getline
上成功,除非用户明确指出文件结尾(Linux上的control-D字符或Windows上的control-Z)。我们可以轻松检查std::cin
是否处于失败状态,循环并创建另一个 - 旧的将自动清理。
我们甚至可以制作一个帮助函数,如:
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
,当然。