Dual validation with a do-while loop and if-else statement - c++

I need to figure out how to validate 2 conditions.
Check if a previous number has been played.
Check if the number is between 1 and 9.
In either case, it should loop back to the beginning. With the first situation, it shouldn't run till the user enters a number that hasnt been played.
do
{
cout << "Interesting move, What is your next choice?: ";
cin >> play;
Pused[1] = play;
if(play != Pused[0] && play != cantuse[0] && play != cantuse[1] )
{
switch(play)
{
default:
cout << "Your choice is incorrect\n\n";
break;
}
}
}while(play != 1 && play != 2 && play != 3 && play != 4
&& play != 5 && play != 6 && play != 7 && play != 8 && play != 9);
Dis_board(board);

Instead of do-while loops, i like to use the combination of infinite loops + break statements, like this:
cout << "What is your first choice? ";
while (true)
{
// Input the choice, including validation
// Do the move
if (game_over)
break;
cout << "Interesting move; what is your next choice? ";
}
In the code above, the two comments represent code, which may itself contain loops. In order to reduce confusion, you might want to stuff this code into a separate function. For example, to input the choice:
while (true)
{
cin >> play;
bool is_illegal =
play == cantuse[0] ||
play == cantuse[1] ||
play < 1 ||
play > 9;
if (is_llegal)
cout << "Your choice is incorrect; please enter again: ";
else
break;
}
Note: to implement good handling of user errors, you also have to account for the case when the user enters nonsense instead of a number; look up istream::ignore and ios::clear for that.

Related

Running a simple C++ function

I've just started learning the basics in C++ and currently am trying to make a program that does a few basic things. The problem I have is occurring in the pasted function below.
At this point it literally does nothing when it runs. All I'm trying to do it make it so the function runs over and over again forever, until the user enters the letter 'q'.
The function must keep running even if the user enters some random string, anything, 'q' is the only keystroke that should stop the loop.
I have tried toying around with 'cin.whatever" and haven't found success. If you have an answer please provide as much explanation as possible. Thank you!
void menu()
{
cin.clear();
cin.ignore();
char quit = 'w';
while (quit != 'q') // while loop to allow the user infinite tries
{
cout << "Which story would you like to play? Enter the number of the story (1, 2, or 3) or type q to quit: " << endl;
cin >> quit;
if (quit < '1' or quit > '3') // make sure the user picks a valid choice
{
cout << "Valid choice not selected." << endl;
}
if (quit == '1')
{
story1(); // run story 1
}
if (quit == '2')
{
story2(); // run story 2
}
if (quit == '3')
{
story3(); // run story 3
}
if (quit == 'q')
{
cout << "good bye" << endl;
break;
}
}
}
Try adding single quotes around your 1,2,3 like you did with the q. The cin is expecting a char to be entered so evaluate it as such. e.g: if (quit == '1')

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++ Checking Against Particular Numbers

Hello Dear Programmers,
I've been working on a piece of code for a while, but I don't seem to figure this out, i'm trying so hard to check an input with a specific number, but so far it ends up not working and even when number 2,3, or 4 is pressed the error message pops up, and I go to my if else condition. here are the codes, number_of_bedrooms is an integer.
out << "Number Of Bedrooms: (Limited To 2,3, and 4 Only)" << endl;
if (isNumber(number_of_bedrooms) == false ) {
cout << "Please Do Enter Numbers Only" << endl;
cin.clear();
}
else if (number_of_bedrooms != '2' || number_of_bedrooms != '3' || number_of_bedrooms != '4') {
cout << "Numbers Are Only Limited To 2,3, And 4" << endl;
cin.clear();
}
and the function :
bool isNumber(int a)
{
if (std::cin >> a)
{
return true;
}
else
{
return false;
}
}
the first validation which checks for numbers works fine, but the second validation no, my guess is the system is not capturing inputted data after that boolean function. And if that's the reason, what's the solution ?!!
Change your || to &&, also you need to compare to int not char
else if (number_of_bedrooms != 2 && number_of_bedrooms != 3 && number_of_bedrooms != 4)
Note that a more general way to solve such a problem (for example if your list got much longer) would be to do something like
std::set<int> const allowableBedrooms = {2,3,4};
else if (allowableBedrooms.find(number_of_bedrooms) == allowableBedrooms.end())
{
// Warn user here
}
As your goal conditions are sequential, I'd use something like this:
else if ( number_of_bedrooms < 2 || number_of_bedrooms > 4 ) {
cout << "Numbers Are Only Limited To 2,3, And 4" << endl;
cin.clear();
}
This is very clear and easy to manage if you want to change it. If you want to enumerate everything you'll need to use && instead of || since your want it to both be not 2 and not 3 and not 4 to trigger the issue.
Another problem in your code is that you're comparing against characters by putting the numbers in single quotes. Since these are integers you should not have them in quotations.
You have to change your function to make the change out of the local function like this:
bool isNumber(int * a)
{
if (std::cin >> * a)
{
return true;
}
else
{
return false;
}
}
And then call the function with the address of number_of_bedrooms like this:
out << "Number Of Bedrooms: (Limited To 2,3, and 4 Only)" << endl;
if (isNumber(&number_of_bedrooms) == false ) {
cout << "Please Do Enter Numbers Only" << endl;
cin.clear();
}
else if (number_of_bedrooms < 2 || number_of_bedrooms > 4) {
cout << "Numbers Are Only Limited To 2,3, And 4" << endl;
cin.clear();
}
Check the code above becouse i took off the '' that means you are comparing number_of_bedrooms (int) with '2' (char) so it will be always true.
The condition i wrote would be better then becouse you are considering an interval of numbers, if you are considering the specific numbers you can leave your condition but you should change the logical operator in && and chain with the other != conditions

Trouble with dual input validaton a C++ program

SO I'm trying to:
Do dual input validation inside a do while loop
Check to see if the move has been made yet and whether it is a logical input. (# 1-9)
I originally thought if else statement but im not sure how to use the else statement to get back to the start of the loop.
do
{
cout << "Interesting move, What is your next choice?: ";
cin >> play;
Pused[1] = play;
if(play != Pused[0] && play != cantuse[0] && play != cantuse[1] )
{
switch(play)
{
default:cout << "Your choice is incorrect\n\n";
break;
}
}
else
{ }
}
while(play != 1 && play != 2 && play != 3 && play != 4 && play != 5 && play != 6 && play != 7 && play != 8 && play != 9);
Dis_board(board);
use "continue" keyword to go back to start of the loop.
Just remove else. I think it is not required. Automatically your loop will be continued if conditions in while are satisfied.
Your question is a bit hard to understand, but you've got a few conditions to solve in this loop:
Ask the user for input
Check if the users input is valid (Between 1-9 and not been used before)
Exit the loop if we have a valid choice
So we need to record what moves have been done and also check that the user's input is within the valid choices, we can use a loop that exits only when a valid choice is chosen.
int choice;
bool used[9] = { false }; // Set all values to false
std::cout << "Interesting move, what is your next choice?: ";
do {
std::cin >> choice;
// Here we check if the choice is within the range we care about
// and not used, note if the first condition isn't true then
// the second condition won't be evaluated, so if choice is 11
// we won't check used[10] because the && will short circuit, this
// lets us avoid array out of bounds. We also need to
// offset the choice by 1 for the array because arrays in C++
// are indexed from 0 so used runs from used[0] to used[8]
if((choice >= 1 && choice <= 9) && !used[choice - 1]) {
// If we're here we have a valid choice, mark it as used
// and leave the loop
used[choice - 1] = true;
break; // Exit the loop regardless of the while condition
}
// If we've made it here it means the above if failed and we have
// an invalid choice. Restart the loop!
std::cout << "\nInvalid choice! Input: ";
} while (true);

C++ input from console, comparing integers

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. :-)