Home > front end >  Input validation C
Input validation C

Time:04-15

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 when count equals std::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 is delim, as determined by Traits::eq_int_type(Traits::to_int_type(c), delim). The delimiter character is extracted and discarded. This test is disabled if delim is Traits::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.

  •  Tags:  
  • c
  • Related