C++ input from console, comparing integers - c++

bool choose() {
int answer = 0;
while(answer != 1 || answer != 2) {
cout << endl << "Do you want to encrypt(enter 1) or decrypt(enter 2)?" << endl;
cin >> answer;
}
if(answer == 1) return true;
return false;
}
What is the best way to read from line and compare input with integers?
I know ways cin , gets , getline(cin, answer) .
Which should I use and why?
At the moment, this way is not working, because when i enter 1 or 2, it still stays in while.

Your condition is incorrect. By De Morgan's laws, you should be using && instead.
while(answer != 1 && answer != 2) {

You're reading the value correctly. However, the loop condition is wrong; it should be
while(answer != 1 && answer != 2)
Using || makes the condition always true, since no number is equal to both 1 and 2.

This code is a very good candidate for do-while loop, and if you use that you're not required to initialize the variable answer.
int answer; //= 0; no need to initialize!
do {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
cin >> answer;
}while(answer != 1 && answer != 2);
And of course, you need to use && as others has already pointed out. :-)
By the way, what would happen if user entered any non-integer input such as hgjkhg? cin>>answer would fail to read the input and it will remain there forever, and the flag of cin will be set failure, and cin will not be able to read futher input. That means, the loop will never exit!
To avoid this, and to make the code more robust and complete you should write it as:
int answer = 0;
while(answer != 1 && answer != 2) {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
if ( !(cin >> answer) )
{
cin.clear(); //clear the failure flag if there is an error when reading!
std::string garbage;
std::getline(cin, garbage); //read the garbage from the stream and throw it away
}
}
Yes. You can use your while loop instead of do-while. All that you need to add the if(!(cin>>answer)) { ... } in your code. :-)

Related

How to ignore wrong cin input in C++?

This is code for a 4x4 tic-tac-toe game. I am new to programming. I don't know how to ignore wrong input from the user. I tried searching Google, I found cin.clear() and cin.ignore(). They did work a little bit, but not fully working. For example, if the user enters 11111111 4 o as input, the program exits instead of ignoring this. How to ignore this input?
And what are cin.clear() and cin.ignore() doing?
char game[4][4];
int r, c;
char ans;
cin >> r >> c >> ans;
--r, --c;
if (!check_ok(r, c, ans)){
cout << "try again: select available ones only!!!\n";
--count;//count checks for 16 turns through while loop
}else{
game[r][c] = ans;
++count1;
}
bool Game::check_ok(int a, int b, char an) {
if (game[a][b] == ' ' && a < 4 && b < 4 && ((count1 % 2 == 0 && an == 'x') || (count1 % 2 != 0 && an == 'o'))){
game[a][b] = an;
return true;
}
else{
cin.clear();
cin.ignore();
return false;
}
}
OK. User input is hard.
Interactive user input is line based.
User inputs some values and then hits return. This flushes the stream and unblocks the readers to get the value from the stream. So you should design your input code to be line based.
The first question seems to be is all the input on one line or do they input the values with a return between each? You can determine this with some outut to the user then follow the rules defined by your instructions.
So lets do a line based input example:
do {
// Your instructions can be better.
std::cout << "Input: Row Col Answer <enter>\n";
// Read the user input. 1 Line of text.
std::string line;
std::getline(std::cin, line);
// convert user input into a seprate stream
// See if we can correctly parse it.
std::stringstream linestream(std::move(line));
// Notice we check if the read worked.
// and that the check_ok() returns true.
// No point in call check_ok() if the read failed.
if (linestream >> r >> c >> ans && check_ok(r, c, ans)) {
break;
}
std::cout << "Invalid Input. Please try again\n";
}
while(true);
i think instead of ignoring the wrong input you should limit the users input into the ideal inputs only. maybe an if statement could help
if(input != ideal_input)
{
cout>>"invalid input";
}
else
{
//progress in the game
}

How do I create a loop that lets the user re-enter their answer when a cin.fail() occurs?

This small segment of my program seems to cause some problems:
cout << "Would you like to change the values? Type 1 if yes or 2 if no." << endl << "You can also reverse the original vector above by typing 3. \n Answer: ";
cin >> yesorno;
while (yesorno != 1 && yesorno != 2 && yesorno != 3 || cin.fail() )
{
cout << "\n Sorry, didn't catch that. Try again: ";
cin >> yesorno;
}
The loop works fine for all valid integers as far as I know, but when an unvalid value gets declared to yesorno the loop freaks out. For example, if I input the letter A, the loop goes on for infinity.
I guess what I'm asking is, how do I make it so that the user gets unlimited amounts of chances to input a valid value?
I'm pretty new to C++ btw so I am not familiar with all different kinds of public member functions etc.. I've tried cin.clear() but didn't have much success
When you run into error in reading input data, you may use cin.clear() to clear the state of the stream and follow it with a call to cin.ignore() to ignore the rest of the line.
while ( (yesorno != 1 && yesorno != 2 && yesorno != 3) || cin.fail() )
{
cout << "\n Sorry, didn't catch that. Try again: ";
if ( cin.fail() )
{
cin.clear();
cin.input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cin >> yesorno;
}
Another approach, that I prefer, is to read the input line by line and process each line independently.
std::string line;
while ( getline(cin, line) )
{
std::istringstr str(line);
if ( !(str >> yesorno) || (yesorno != 1 && yesorno != 2 && yesorno != 3) )
{
cout << "\n Sorry, didn't catch that. Try again: ";
continue;
}
else
{
// Got good input. Break out of the loop.
break;
}
}
When the fail bit gets set, you need to clear it before continuing.
while (yesorno != 1 && yesorno != 2 && yesorno != 3 || cin.fail() )
{
if ( cin.fail() ) {
cin.clear();
cin.ignore( std::numeric_limits<std::streamsize>::max() );
}
cout << "\n Sorry, didn't catch that. Try again: ";
cin >> yesorno;
}

C++ equality check on char from cin against another char never equates to true??? (No compiler errors)

I'm stuck as to why the condition below isn't triggering when either an 'n' or a 'y' is entered at the console. When executed you can't get out the the if statement, but i know for sure that
!(cin >> again)
isn't the culprit, as that was previously the only condition in the if statement and I was able to skip/enter the if block if a character/numeral was entered, which was as expected. Here is the code:
char again;
while (1) {
cout << endl;
cout << "I see another one, care to shoot again? (y/n): ";
if (!(cin >> again) || (again != 'n') || (again != 'y')) {
// Error checking for numberals & non 'y' or 'n' characters
cout << "Please enter 'y' or 'n' only." << endl;
cin.clear();
cin.ignore(1000, '\n');
continue;
}
break;
}
I'm stumped on this so any help would be hugely appreciated!
if(...|| (again != 'n') || (again != 'y')) {
is faulty logic. What you say is
if "again" is not n or it's not y, then do the following...
now, since "again" can't be n and y at the same time, this always evaluates to true; most probably, even your compiler notices that and just jumps right into your if's content.
What you want is something like
if(!(cin>>again) || ( again != 'n' && again != 'y') {
Because that reads
if cin>>again didn't work or again is neither n nor y then,...

c++ cin only boolean(0,1)

I wish to achieve to limit user on only 0 or 1 when program asking for boolean variable.
I'we tried to do so, but it doesn't work. It still keep asking me for typing in.
bool ele;
do{
cout << "Elektro:\t";
cin >> ele;
if (cin && ele == 0 && ele == 1) break;
cin.clear();
cout << "Neveljaven vnos!" << endl;
}while(true);
The good news is, that operator>> for bool by default allows only '0' or '1' as valid input. That means you don't need to explicitly check the value after read - if stream state is ok, so is your bool:
bool ele;
if (!(cin >> ele)) {
// error;
}
The reason you're getting an infinite loop when you enter something like "cvdsavd" is that you only clear the error flags, but don't get rid of the bad charaters. So your loop keeps trying but never can get a valid input. You need to get rid of the garbage:
bool ele;
while (!(std::cin >> ele)) {
std::cout << "Neveljaven vnos!\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Reference for ignore(). You also need to include <limits> for numeric_limits template.
Lp :)
As chris points out, you want to do if (cin && (ele == 0 || ele == 1)) break;
You cant do that :
if (cin && ele == 0 && ele == 1) break;
because its always false because ele cant be in same time 1 or 0 ... It can be only one of this figures.
if(ele == 0 || ele == 1) break;

Problem with input in c++

I have a very basic question i want to take integer input in certain range from user. if the user gives some string or char instead of integer. then my program goes to infinite loop.
my code is some what like that
cin >> intInput;
while(intInput > 4 || intInput < 1 ){
cout << "WrongInput "<< endl;
cin >> intInput;
}
I am only allowed to use c++ libraries not the c libraries.
As mentioned in the possible duplicate, you should check the state of cin on each loop.
Possible implementation:
if(cin >> intInput)
while(intInput > 4 || intInput < 1 ){
cout << "WrongInput "<< endl;
if(!(cin >> intInput)){ break; }
}
Very ugly code, just trying to illuminate the answer which is to check the state of cin.
The solution to this answer is to always read lines from the standard input.
std::string input; int value = 0;
do
{
// read the user's input. they typed a line, read a line.
if ( !std::getline(std::cin,input) )
{
// could not read input, handle error!
}
// attemp conversion of input to integer.
std::istringstream parser(input);
if ( !(parser >> value) )
{
// input wasn't an integer, it's OK, we'll keep looping!
}
}
// start over
while ((value > 4) || (value < 1));
#include <locale>
..
if(!isalpha(intInput)) {
..
}
Note, this won't work if, for example the user enters a "+" but maybe it will put you in the right direction..