patterncppMinor
User input validation that might be unbreakable for C++
Viewed 0 times
mightuservalidationinputunbreakablethatfor
Problem
I am new to programming and have been having a lot of trouble with user input validation. Everything I found online I could break and I finally put this function together that appears to be unbreakable. It is for
I am curious about how it might be critiqued by experienced programmers. How did I do? What can be improved? What are some issues I might run into? One issue I ran into was when I
int and double specifically.I am curious about how it might be critiqued by experienced programmers. How did I do? What can be improved? What are some issues I might run into? One issue I ran into was when I
#include, max() becomes an issue in this code, so I had to use #define NOMINMAX. I wonder if there is a way around that as well. I am using this code with Visual C++ in Visual Studio.#include
#include
#include
using namespace std;
template
void input(T& input, int low, int high, string message)
{
input = low - 1;
while (input high)
{
cout > input).fail() || cin.peek() != '\n')
{
cin.clear();
cin.ignore(numeric_limits::max(), '\n');
cout ::max(), '\n');
}
}Solution
-
The
-
Seeing as we only want to output our message
-
I would change the function signature to make it easier to use in client code. Instead of passing in a temp var for input, just let the function return type
-
The type of low and high should be of the same type as
-
Finally we do not wish to modify low or high and should also pass them by
The final function might then look something like
The
#define NOMINMAX issue is easy to fix. To do so we need to remove(or move internally to our input function) the using namespace std; call as this pollutes our global namespace with max/min calls. See this for why it is bad practice to include the namespace.-
Seeing as we only want to output our message
string and do not care about copying, it is best to pass this to our function as const& std::string-
I would change the function signature to make it easier to use in client code. Instead of passing in a temp var for input, just let the function return type
T.-
The type of low and high should be of the same type as
T, not always int. For types such as double and float the comparisons may not always return expected results and may also need to be compared with some small epsilon value.-
Finally we do not wish to modify low or high and should also pass them by
const.The final function might then look something like
#include
#include
#include
template
T ValidateInput(const T low, const T high, const std::string& message)
{
using namespace std;
T input = low - 1;
while (input high)
{
cout > input).fail() || cin.peek() != '\n')
{
cin.clear();
cin.ignore(numeric_limits::max(), '\n');
cout ::max(), '\n');
}
return input;
}Code Snippets
#include<iostream>
#include<string>
#include<limits>
template<class T>
T ValidateInput(const T low, const T high, const std::string& message)
{
using namespace std;
T input = low - 1;
while (input < low || input > high)
{
cout << message;
while ((cin >> input).fail() || cin.peek() != '\n')
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << message;
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return input;
}Context
StackExchange Code Review Q#161061, answer score: 3
Revisions (0)
No revisions yet.