我正在介绍C ++,我在Win7上使用VStudio 2013。我尽量避免从我的菜单中输入错误的数据,并且除了这个之外,它在所有这些中都有效。
cout << "Please choose your second number" << endl;
cin >> move2;
if (move2 < 1 || move2 > size)
{
cout << "That's not a valid move" << endl;
Sleep(2000);
cin.sync();
cin.clear();
}
唯一的区别是在移动条件下&gt;变量(大小)而不是数字。当我输入一个字符时,它会回到询问另一个输入的问题,但如果我输入一个字,它就会中断!
我尝试使用cin.ignore(numeric_limits<streamsize>::max(), '\n');
,但编译器突出显示max()
,并说“期待标识符”。
对于所有优秀的程序员来说,这可能很容易,但我不知道如何修复它。有人能帮助我吗?
答案 0 :(得分:19)
这是因为在Visual Studio中使用windows时,它会定义一个宏max()。如果将鼠标悬停在示例中的max()上,则应收到智能警告。您可以通过在所有包含之后和任何代码之前取消定义max来解决此问题。
#undef max
答案 1 :(得分:4)
要使用std::numeric_limits<T>
,您需要加入<limits>
。此外,传递给它的类型需要知道和实际上是std::streamsize
类型,即我会将其用作
#include <iostream>
#include <limits>
// ...
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
此外,您应该确保尝试阅读某些内容实际上是成功的,如果不是,则首先clear()
该流的状态。这是一个完整的程序(它肯定会编译并运行gcc和clang):
#include <iostream>
#include <limits>
int main()
{
int move2, size(3);
while (!(std::cin >> move2) || move2 < 1 || size < move2) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "invalid input ignored; please enter a valid move\n";
}
std::cout << "move2=" << move2 << '\n';
}
答案 2 :(得分:0)
限制潜在副作用的代码
在我的测试中,似乎不需要#undef max
之前完成#include
。
通常,您可能希望通过以下方法来限制潜在的副作用:首先推入max
宏,然后对其进行取消定义,然后使用<limits.h>
中的max像这样将其弹出(仅在Windows / Visual上进行了测试Studio 2019):
// stuff ...
#pragma push_macro("max")
#undef max
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
#pragma pop_macro("max")
// more stuff ...
请参阅Microsoft文档:push_macro和pop_macro
将其放入函数中使其干燥:
void CinIgnore() {
#pragma push_macro("max")
#undef max
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
#pragma pop_macro("max")
}
添加std::cin.clear
以实现CinReset
功能:
void CinReset() {
std::cin.clear();
#pragma push_macro("max")
#undef max
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
#pragma pop_macro("max")
}
其他信息:ignore
上的cppreference.com article是有效使用clear
和ignore
以及状态标记的一个很好的例子,但是没有上面提到的Windows / Visual Studio必需的修复程序。
注意:尽管上述操作是标准操作,但不适用于用户以交互方式输入EOF的用户(ctrl-z
-使用Visual Studio的Windows)。我编写了一个IStreamUtils
类,其中包含一个更可靠的Reset方法。稍后,我将在此处添加有关该文章的链接。
答案 3 :(得分:-1)
如果cin有错误,则以下内容将清除错误状态,然后读取该行的其余部分。
if(!cin)
{
cin.clear();
string junk;
getline(cin, junk);
}
答案 4 :(得分:-2)
包括:
#include <climits>
看看是否有帮助。我遇到了同样的问题,当我将其从限制改为攀登时,它已得到解决。