cin.ignore(numeric_limits::max(), '\n'); max() not recognize it

前端 未结 5 1939
北恋
北恋 2020-12-13 20:44

I\'m taking an intro to C++, and I\'m using VStudio 2013 on Win7. I try to avoid the wrong data input from my menus, and it\'s working in all of them except this one.

<
相关标签:
5条回答
  • 2020-12-13 21:05

    To use std::numeric_limits<T> you'll need to include <limits>. Further, the type passed to it need to be known and actually the type std::streamsize, i.e., I would use it as

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

    Also, you should probably make sure that your attempt to read something was actually successful and, if it was not, first clear() the stream's state. Here is a complete program (it certainly compiles and runs with gcc and 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';
    }
    
    0 讨论(0)
  • 2020-12-13 21:12

    If cin has an error the following will clear the error state and then read in the rest of the line.

    if(!cin)
    {
       cin.clear();
       string junk;
       getline(cin, junk);
    }
    
    0 讨论(0)
  • 2020-12-13 21:16

    Include:

    #include <climits> 
    

    and see if that helps. I had the same issue and when I changed it from limits to climits it was resolved.

    0 讨论(0)
  • 2020-12-13 21:18

    Code that Limits Potential Side Effects

    In my testing, #undef max does not seem to need to be done before any #includes.

    You might want to limit potential side effects in general by first pushing the max macro, then undefining it, then popping it off after using max from <limits.h> like this (only tested on 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 ...
    

    See the Microsoft Docs: push_macro and pop_macro

    Put it in a function to make it DRY:

    void CinIgnore() {
    
    #pragma push_macro("max")
    #undef max
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    #pragma pop_macro("max")
    
    }
    

    Add std::cin.clear to make a CinReset function:

    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")
    
    }
    

    Additional information: this cppreference.com article on ignorehas a good example of how to use clear and ignore, along with state flags, effectively, but does not have the necessary fix for Windows/Visual Studio noted above.

    NOTE: The above, though standard, does not work well with the user interactively inputting EOF (ctrl-z - Windows using Visual Studio). I have written a IStreamUtils class that includes a Reset method that is more robust. I will add a link to an article about that here later.

    0 讨论(0)
  • 2020-12-13 21:21

    This is because in Visual Studio when you use the windows includes it will define a macro max(). If you hover over the max() in your example you should receive an intellisense warning. You can solve this problem by undefining max after all your includes and before any code.

    #undef max
    
    0 讨论(0)
提交回复
热议问题