【问题标题】:cin.ignore(numeric_limits<streamsize>::max(), '\n'); max() not recognize itcin.ignore(numeric_limits<streamsize>::max(), '\n'); max() 无法识别
【发布时间】:2013-12-07 20:41:25
【问题描述】:

我正在介绍 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();
    }

唯一的区别是在 move > 的条件中是一个变量(大小)而不是一个数字。当我输入一个字符时,它会回到要求另一个输入的问题,但是如果我输入一个单词,它就会中断!

我尝试使用cin.ignore(numeric_limits&lt;streamsize&gt;::max(), '\n');,但编译器会突出显示max(),并显示“期望标识符”。

对于你们所有优秀的程序员来说,这可能很容易,但我不知道如何解决它。有人可以帮帮我吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    这是因为在 Visual Studio 中,当您使用 windows 包含时,它会定义一个宏 max()。如果您将鼠标悬停在示例中的 max() 上,您应该会收到一个智能感知警告。您可以通过在所有包含之后和任何代码之前取消定义 max 来解决此问题。

    #undef max
    

    【讨论】:

      【解决方案2】:

      要使用std::numeric_limits&lt;T&gt;,您需要包含&lt;limits&gt;。此外,传递给它的类型需要知道并且实际上是类型std::streamsize,也就是说,我会将它用作

      #include <iostream>
      #include <limits>
      // ...
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      

      此外,您可能应该确保您尝试读取某些内容实际上是成功的,如果没有成功,首先要确保clear() 流的状态。这是一个完整的程序(它当然可以使用gccclang 编译和运行):

      #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';
      }
      

      【讨论】:

      • 感谢您快速回复迪特玛。我尝试这样做并包含 ,但现在突出显示了streamsize并且它说...类型名称是不允许的。我错过了另一个图书馆吗??
      • @user3078454:抱歉,我在移动设备上输入了这些内容,而第二个版本使用了完全错误的表达方式。我刚刚编辑了答案来修复它。
      • 也许我应该添加整个函数
      【解决方案3】:

      限制潜在副作用的代码

      在我的测试中,#undef max 似乎不需要在任何#includes 之前完成。

      您可能希望通过首先推送 max 宏,然后取消定义它,然后在使用 &lt;limits.h&gt; 中的 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_macropop_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 有一个很好的示例,说明如何有效地使用 clearignore 以及状态标志,但没有针对 Windows/Visual Studio 进行必要的修复以上。

      注意:上述内容虽然是标准的,但不适用于用户交互式输入 EOF(ctrl-z - 使用 Visual Studio 的 Windows)。我编写了一个 IStreamUtils 类,其中包含一个更强大的 Reset 方法。稍后我将在此处添加相关文章的链接。

      【讨论】:

        【解决方案4】:

        如果 cin 有错误,以下将清除错误状态,然后读取该行的其余部分。

        if(!cin)
        {
           cin.clear();
           string junk;
           getline(cin, junk);
        }
        

        【讨论】:

        • 我试过了,还是不行。它仅适用于超出范围的数字,但不适用于字符串
        【解决方案5】:

        包括:

        #include <climits> 
        

        看看是否有帮助。我遇到了同样的问题,当我将它从限制更改为限制时,它得到了解决。

        【讨论】:

        • 需要 OP &lt;limits&gt;,而不是 &lt;climits&gt;。 Dietmar Kühl 在他的回答中已经说过了……
        • 我遇到了同样的问题,限制什么也没做。 Climits 修复了它。
        • 这很奇怪。 1.numeric_limits来自&lt;limits&gt;。 2. 你确定你有完全同样的问题吗?因为 OP 的修复似乎是 #undef max
        • 是的。我只使用了那行代码 并且它有效?也许是因为我使用 Geany .. 这也很奇怪,但我不知道为什么我的不需要
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-11
        • 2012-12-01
        • 1970-01-01
        • 2012-03-01
        • 1970-01-01
        相关资源
        最近更新 更多