I need help with input validator, whenever the console gets a wrong input, it does the job to determine whether the input is valid or not but here I have a problem where if I put a wrong input first, I have to re-enter the next input twice for it to go to Enter operator
line.
#include <iostream>
#include <windows.h>
using namespace std;
main()
{
// Declaring variables
float num1;
char user_operator;
// Code Structure
cout << "Junie's C Calculator v.1" << endl << endl;
cout << "Enter first number >> ";
// Error checking Input
while (! (cin >> num1))
{
system("CLS");
cout << "Junie's C Calculator v.1\n\n";
// Clear the input
cin.clear();
cin.ignore();
// Ask for the input again
cout << "(!) Enter first number >> ";
cin >> num1;
}
cout << "Enter operator >> ";
}
CodePudding user response:
I have to re-enter the next input twice
That is because you are asking for input twice:
while (! (cin >> num1))
{
...
// Ask for the input again
cout << "(!) Enter first number >> ";
cin >> num1; // <--
}
If the user enters bad input, !(cin >> num1)
is true, so the loop is entered, and then cin >> num1
gets executed twice, once at the end of the current loop iteration, and then again in the while
condition of the next loop iteration. The next loop iteration will only evaluate the 2nd input.
So, you need to remove the cin >> num1
at the end of the loop:
while (! (cin >> num1))
{
...
// Ask for the input again
cout << "(!) Enter first number >> ";
// cin >> num1; // <-- remove this!
}
On a separate note:
cin.ignore();
ignores only 1 character, but more times than not you need to ignore more characters than that. It is customary to use this instead:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Which will ignore all characters up to the next Enter entered by the user. Using numeric_limits<streamsize>::max()
as the number of characters to ignore is handled as a special-case:
https://en.cppreference.com/w/cpp/io/basic_istream/ignore
ignore
behaves as an UnformattedInputFunction. After constructing and checking the sentry object, it extracts characters from the stream and discards them until any of the following conditions occurs:
count
characters were extracted. This test is disabled in the special case whencount
equalsstd::numeric_limits<std::streamsize>::max()
end of file conditions occurs in the input sequence, in which case the function calls
setstate(eofbit)
the next available character
c
in the input sequence isdelim
, as determined byTraits::eq_int_type(Traits::to_int_type(c), delim)
. The delimiter character is extracted and discarded. This test is disabled ifdelim
isTraits::eof()
This is basically telling ignore()
to not keep track of the count at all, just keep ignoring everything until another condition tells it to stop. If you specify any other value for the count
, ignore()
will have to keep track of how many characters it has ignored and then exit when that count has been reached. And there is no standard to how many characters constitute a line of input. Different console implementations have different limits on line input.