C++ input validation - program is reading wrong values/not reading values - c++

I am fairly new to C++ and need some help on a tic-tac-toe project that I am working on. Everything is completed except for the input, which I am having a lot of trouble with. Relevant pieces of my code and some input that breaks the program is below.
cout << "Your move. Where would you like to play? Enter the row. Note that the row numbering starts at 0." << endl; // Ask for user input for move
if(started)
{
cin.clear(); // Clear cin fail bit
cin.sync(); // Sync cin buffer to get rid of lines left over
}
cin >> moveX; // Get row input from user
cin.ignore(10000, '\n'); // Ignore rest of line
cin.sync(); // Sync cin buffer to get rid of lines left over
if(validateMoveX(moveX) == -1) // If the move was not validated
{
cout << "TOO MANY INVALID ATTEMPTS...EXITING" << endl << endl; // Tell the user that there were too many invalid attempts
return ' '; // Return a space to main
}
cout << "Your move. Where would you like to play? Enter the column. Note that the column numbering starts at 0." << endl; // Ask for user input for move
cin.sync(); // Sync cin buffer to get rid of letters stuck in buffer
cin.clear(); // Clear cin fail bit
cin >> moveY; // Get the column input from user
cin.sync(); // Sync buffer to get rid of letters left over
cin.clear(); // Clear cin fail bit
cin.ignore(10000, '\n'); // Ignore rest of line
if(validateMoveY(moveX, moveY, miniBoard) == -1) // If the move was not validated
{
cout << "TOO MANY INVALID ATTEMPTS...EXITING" << endl << endl; // Tell the user that there were too many invalid attempts
return ' '; // Return space to main
}
Above is my code from the function that actually plays the game and calls all the other functions that are used in my program. I think this is where the issue lies, but I am not certain. The issue could also be in my Y-input validation function (probably the cin.ignore() line just before cin >> moveY). I think my X-input validation function is fine (again, not 100% sure)
Code from my function to validate user input for rows: https://pastebin.com/v3VtLbJ4
Code from my function to validate user input for columns: https://pastebin.com/cqfWTc05
Test data that breaks program:
Row input: 1 2
Column input: asdjfasjldksk sdlfasl ljk (basically random input)
Problem: Program reads this as "Play a move at 1, 0"
OR
Row input: put something random
Column input: 100000000000
After the program asks to re-enter input for the column: 1
Problem: The second "1" is not read

Related

Catch cin exception

I want to ask the user for input, which I get with cin like this
void AskForGroundstate() {
cout << "Please enter an groundstate potential value in Volt:" << endl;
if (!(cin >> _VGroundstate)) {
cin.clear();
cin.ignore();
cout << "Groundstate potential not valid." << endl;
AskForGroundstate();
}
}
_VGroundstate is a double, so if the user enters an String with not numbers, it should ask him again for a better input. But the problem is, that when the input is for example "AA", than the program executes AskForGroundstate two times, with "AAA" three times etc. Did I use the clear wrong?
The problem is that cin.ignore() drops one character; you want to drop all characters to end of line:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
This ensures that all invalid input is dropped before end-users are prompted for input again.

Stopping the user from entering letters? C++

Hi i'm newish to C++ but i have a little problem which is i have to stop the user entering letters in a number section. I have made an attempt which works but its dodgy, because it will allow the user to continue then will tell them they have got something wrong and to restart the application. How do i validate it to bring up an error message telling them thats not a number and let them re enter a number?
Here is the code:
double Rheight;
do
{
cout << "Enter height of the room. " << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
cout << "WARNING: If you enter a letter the program will exit." << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
cin >> Rheight;
}
while (Rheight > 20 || Rheight == 0);
Ask if you need to see more code.
There are basically two components to the answer:
Detecting that the input failed.
Cleaning up after a failed input.
The first part is rather trivial: you should always test after input that the stream is in a good state before using the input. For example:
if (std::cin >> value) {
// use value
}
else {
// deal with the input error
}
How to deal with the input error depends on your needs. When reading a file you'd probably abort reading the entire file. When reading from standard input you can ignore just the next character, the entire line, etc. Most like you'd want to ignore the entire line. Before doing so you'll need to put the stream back into a good state:
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
The first line clears the stream's error flags and the second line is a magic incantation ignoring as many characters as necessary until a newline got ignored.
To check if the input was valid you can use
if(!(cin >> Rheight))
{
cout << "Please input a valid number!" << endl;
continue;
}

cin condition checking error

I am a beginner programmer learning c++. I am having a nagging issue with the cin command.
In the program section below, if I enter a wrong type at the 1st cin command, the program will not execute any of the following cin commands at all, but will execute the rest of the program.
//start
#include <iostream>
using namespace std;
int main()
{
int x=0;
cout << endl << "Enter an integer" << endl;
//enter integer here. If wrong type is entered, goes to else
if (cin >> x){
cout << "The value is " << x << endl;
}
else {
cout << "You made a mistake" << endl; //executes
cin.ignore();
cin.clear();
}
cout << "Check 1" << endl; //executes
cin >> x; //skips
cout << "Check 2" << endl; //executes
cin >> x; //skips
return 0;
}
//end
Instead of the if else, if i put the same concept in a loop
while (!(cin >> x))
the program goes into an infinite loop upon enterring a wrong input.
Please help me explain this phenomenon, as the text book i am following says the code typed above should work as intended.
Thank you
cin is an input stream. If an error occurs cin goes into a let's call it "error occured" state. While in this state no character input can be made, your request to collect a character from the input stream will be ignored. With clear() you clear the error and the input stream stops ignoring you.
Here is the ignore function prototype
istream& ignore ( streamsize n = 1, int delim = EOF );
This function gets characters from the input stream and discards them, but you can't get any character if your stream is ignoring you, so you have to first clear() the stream then ignore() it.
Also, a note on the side: If someone inputs, for example "abc", on the first input request your cin gets only one character that is 'a' and "bc" stays in the buffer waiting to be picked up, but the next call to cin gets the 'b' and 'c' stays in the buffer, so you again end up with an error.
The problem with this example is that the cin.ignore() if no arguments are handed to it only ignores 1 character after you clear(). and the second cin gets 'c' so you still have a problem.
A general solution to this problem would be to call
cin.ignore(10000, '\n');
The first number just has to be some huge number that you don't expect someone would enter, I usually put in 10000.
This call makes sure that you pick up all the characters from the false input or that you pick up every character before the enter was pressed so your input stream doesn't get into the "error occurred" state twice.
You may also want to try
if ( std::cin.fail() )
as a backup to prevent a crash due to input of the wrong type when prompted

Checking For Valid Input

I am currently working on a c++ program and I want to check to see if the input the user is making is valid. Currently my code works if the user inputs the proper input or if the user inputs a small incorrect number my pogram will tell the user that the input is invalid. Now my problem is that when the user inputs multiple characters/letters or a large number that has 9 or more digits in it my program goes into an infinate loop giving them the error message. The following is my code:
//for (;;)
while (flag== false)
{
cin >> Input;
if (Input <= choice.size()-1)
{
flag = true;
// break;
}
else
{
cerr << "Input <" << Input << "> is Invalid, Please Choose a Valid Option\n";
userInput = 0;
}
}
As you can see I have also tried doing an infinate for loop but it gives me the same results.
In my code i am printing a vector to the screen. Basicly the user it picking the vectors value to use it.
I am open to any suggestions. Thanks
If the user types in something that can't be read into Input (it's not clear from your code what type Input is), that input will get stuck in the input stream and each iteration of the loop will keep failing to read in the input until you clear the stream.
You need to clear the stream flags and get rid of whatever bad input is waiting in the stream after each failure to read. Try something like this:
while(!(cin >> Input) || Input <= choice.size()-1)
{
cerr << "Input <" << Input << "> is Invalid, Please Choose a Valid Option\n";
cin.clear(); // Clears the input stream fail flag
cin.ignore(100, '\n'); // Ignores any characters left in the stream
}

Else statement crashes when i enter a letter for a cin << int value

Alright, I have a question, I veered away from using strings for selection so now I use an integer. When the user enters a number then the game progresses. If they enter a wrong character it SHOULD give the else statement, however if I enter a letter or character the system goes into an endless loop effect then crashes. Is there a way to give the else statement even if the user defines the variable's type.
// action variable;
int c_action:
if (c_action == 1){
// enemy attack and user attack with added effect buffer.
///////////////////////////////////////////////////////
u_attack = userAttack(userAtk, weapons);
enemyHP = enemyHP - u_attack;
cout << " charging at the enemy you do " << u_attack << "damage" << endl;
e_attack = enemyAttack(enemyAtk);
userHP = userHP - e_attack;
cout << "however he lashes back causing you to have " << userHP << "health left " << endl << endl << endl << endl;
//end of ATTACK ACTION
}else{
cout << "invalid actions" << endl;
goto ACTIONS;
}
You haven't shown how you are reading the integer. But in general you want to do something like this:
int answer;
if (cin >> answer)
{
// the user input a valid integer, process it
}
else
{
// the user didn't enter a valid integer
// now you probably want to consume the rest of the input until newline and
// re-prompt the user
}
The problem is that your cin is grabbing the character and then failing, which leaves the character in the input buffer. You need to check whether the cin worked:
if( cin >> k) { ... }
or
cin >>k;
if(!cin.fail()) { ... }
and if it fails, clear the buffer and the fail bit:
cin.clear(); // clears the fail bit
cin.ignore(numeric_limits<streamsize>::max()); // ignore all the characters currently in the stream
EDIT: numeric_limits is found in the limits header file, which you include as per usual:
#include <limits>
Your problem is not with the else-statement, but with your input. If you do something like
cin >> i;
and enter a character, the streams error state is set and any subsequent try to read from the stream will fail unless you reset the error state first.
You should read a string instead and convert the strings contents to integer.