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.
<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';
}
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);
}
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.
Code that Limits Potential Side Effects
In my testing, #undef max
does not seem to need to be done before any #include
s.
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 ignore
has 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.
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