C++ Checking Against Particular Numbers - c++

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

Related

C++ | For Loop Efficiency?

I've been learning C++ and obviously before hitting loops, the tuition manual I've been reading provided me with this scenario:
Expand the password checking program from earlier in this chapter and make it take multiple usernames, each with their own password, and ensure that the right username is used for the right password. Provide the ability to prompt users again if the first login attempt failed. Think about how easy (or hard) it is to do this for a lot of usernames and passwords.
Without any knowledge yet of loops and whatnot that'll repeat any incorrect values prompting the user to input the correct information until they do so, I've attempted to complete the task and ended up with this code here:
#include < iostream >
using namespace std;
int main()
{
int inputCodeOne, inputCodeTwo = 0;
bool correctPassOne=false,correctPassTwo;
cout << "Please enter your first Code: ";
cin >> inputCodeOne;
if(inputCodeOne==1111||inputCodeOne==2222||inputCodeOne==3333)
{
correctPassOne = true;
}
if (correctPassOne)
{
cout << "Please enter your second Code: ";
cin >> inputCodeTwo;
if (inputCodeOne == 1111 && inputCodeTwo == 100)
{
cout << "Password Correct! Welcome back David";
return 0;
}
else if (inputCodeOne == 2222 && inputCodeTwo == 200)
{
cout << "Password Correct! Welcome back Darren";
return 0;
}
else if (inputCodeOne == 3333 && inputCodeTwo == 300)
{
cout << "Password Correct! Welcome back Jake";
return 0;
}
correctPassTwo = false;
if(!correctPassTwo)
{
cout << "Please re-enter your second Code: ";
cin >> inputCodeTwo;
if (inputCodeOne == 1111 && inputCodeTwo == 100)
{
cout << "Password Correct! Welcome back David";
return 0;
}
else if (inputCodeOne == 2222 && inputCodeTwo == 200)
{
cout << "Password Correct! Welcome back Darren";
return 0;
}
else if (inputCodeOne == 3333 && inputCodeTwo == 300)
{
cout << "Password Correct! Welcome back Jake";
return 0;
}
cout << "ACCESS DENIED";
return 0;
}
}
else
{
cout << "Please re-enter your first Code: ";
cin >> inputCodeOne;
if (inputCodeOne == 1111 && inputCodeTwo == 100)
{
cout << "Password Correct! Welcome back David";
return 0;
}
else if (inputCodeOne == 2222 && inputCodeTwo == 200)
{
cout << "Password Correct! Welcome back Darren";
return 0;
}
else if (inputCodeOne == 3333 && inputCodeTwo == 300)
{
cout << "Password Correct! Welcome back Jake";
return 0;
}
else
{
cout << "Please enter your second Code: ";
cin >> inputCodeTwo;
if (inputCodeOne == 1111 && inputCodeTwo == 100)
{
cout << "Password Correct! Welcome back David";
return 0;
}
else if (inputCodeOne == 2222 && inputCodeTwo == 200)
{
cout << "Password Correct! Welcome back Darren";
return 0;
}
else if (inputCodeOne == 3333 && inputCodeTwo == 300)
{
cout << "Password Correct! Welcome back Jake";
return 0;
}
correctPassTwo = false;
if (!correctPassTwo)
{
cout << "Please re-enter your second Code: ";
cin >> inputCodeTwo;
if (inputCodeOne == 1111 && inputCodeTwo == 100)
{
cout << "Password Correct! Welcome back David";
return 0;
}
else if (inputCodeOne == 2222 && inputCodeTwo == 200)
{
cout << "Password Correct! Welcome back Darren";
return 0;
}
else if (inputCodeOne == 3333 && inputCodeTwo == 300)
{
cout << "Password Correct! Welcome back Jake";
return 0;
}
else
{
cout << "ACCESS DENIED";
return 0;
}
}
}
}
}
Apologies for how messy the code probably is, but I wanted to know if there were any ways to make this more space efficient whilst providing the same result.
Optimization -- First Pass
Create indentifiers or named constants
This allows you to avoid duplication and making typos. Also allows for compiler to make more optimizations.
const int PASSWORD1a = 1111;
const int PASSWORD2a = 2222;
const int PASSWORD3a = 3333;
const int PASSWORD1b = 100;
const int PASSWORD2b = 200;
const int PASSWORD3b = 300;
Group passwords together.
Keeping the passwords paired together will make the process more generic.
You could use the existing std::pair or create your own:
struct Password_Entry
{
int first;
int second;
};
Next, create a table of valid password pairs:
const Password_Entry valid_passwords[] =
{
{PASSWORD1a, PASSWORD1b},
{PASSWORD2a, PASSWORD2b},
{PASSWORD3a, PASSWORD3b},
};
const size_t quantity_valid_passwords =
sizeof(valid_passwords) / sizeof(valid_passwords[0]);
Search the table for valid passwords
int inputCode1;
int inputCode2;
bool passwords_are_valid = false;
std::cout << "Enter first password: ";
std::cin >> inputCode1;
for (unsigned int index = 0; index < quantity_valid_passwords; ++index)
{
if (inputCode1 == valid_passwords[i].first)
{
std::cout << "Enter second password: ";
std::cin >> inputCode2;
if (inputCode2 == valid_passwords[i].second)
{
passwords_are_valid = true;
}
}
}
Summary
The above code is table driven. The code to search the table is generic and depends on the data in the table. The quantity of entries can be changed without having to modify the remaining code.
Pairing the first password with the second, in a structure, allows for more optimal data storage and code space.
Using named constants allows for the value to only be specified once. If you need to change the value, you only make one change. You don't make the risk of skipping past one or more when making the changes.
Optimization -- Second Pass
Person name
Printing of the person's name can be optimized by adding another field or member to the structure:
struct Password_Entry
{
int first;
int second;
char * name;
};
The table now becomes:
const Password_Entry valid_passwords[] =
{
{PASSWORD1a, PASSWORD1b, "David"},
{PASSWORD2a, PASSWORD2b, "Darren"},
{PASSWORD3a, PASSWORD3b, "Jake"},
};
const size_t quantity_valid_passwords =
sizeof(valid_passwords) / sizeof(valid_passwords[0]);
The search / validation code is changed as:
std::cout << "Enter second password: ";
std::cin >> inputCode2;
if (inputCode2 == valid_passwords[i].second)
{
passwords_are_valid = true;
std::cout << "Password Correct! Welcome Back "
<< valid_passwords[i].name
<< "!\n";
}
Optimization -- Third Pass
Consolidation of duplicate text
There is duplicate text, which means that more space can be squeezed out:
char const * const text_enter[] = "Enter ";
char const * const text_password[] = "password";
The code can be changed as:
std::cout << text_enter << "first " << text_password << ": ";
//...
std::cout << text_enter << "second " << text_password << ": ";
//...
std::cout << "Correct " << text_password << "! Welcome Back "
<< valid_passwords[index].name << "\n";
Block Writing
You may be able to squeeze some code space by block writing instead of using formatted writing. All the output is text, so there is no need to format; the text can be directly output. You'll have to compare assembly language listings of before this optimization and after to measure the space difference.
This technique may also show some speed improvements.
Use the following:
std::cout.write(text_enter, sizeof(text_enter) - 1U); // -1 so the terminating nul is not output.
std::cout.write(text_password, sizeof(text_password) - 1U);
std::cout.write(": ", 2);
Likewise, replace the other std::cout << with std::cout.write like the code above.
Optimization -- Fourth Pass
Don't use std::cout.
The std::cout may carry extra baggage with it. You can save some code space by using an alternative.
Replace std::cout with fwrite(stdout, /*...*/).
The fwrite function contains minimal code to write to the given stream. No extra code to format or convert. Plain and simple, write the data to the stream.
Some compilers may be lazy and insert a "one-size-fits-all" library rather than only the code for fwrite.
You may be able to squeeze out more code space by accessing the low level drivers of your operating system directly. Your program is small enough that it doesn't need buffering and some other overhead from the C++ and OS streams. At this point, the space savings may be negligible to the development time spent achieving this. Depends on your platform. On memory constrained systems, this may be a worthwhile endeavor. On most desktop systems, this is not worth your development time, as they have more memory than the constrained systems.
As Jesper commented, yes there are many ways. I'd encourage you to learn about loops first and then revisit this.
Loops just allow you to do the same thing again, anywhere from no times at all (loop doesn't run) to forever (infinite loop).
Anytime you find yourself typing the same thing again or copy-pasting, there is a very high chance that using a loop (or moving code into a function, a class, etc.) would be a better option.
Also, your code doesn't appear to behave as intended. If you initially type the incorrect input, correctPassOne is false, and you going into the first else and prompted to "re-enter your first code:".
The first set of if else statements will never pass. It's checking if inputCodeTwo is correct but it has never been given by the user at this point.
It seems like you recognized this and put the else statement after that which then prompts for inputCodeTwo.
The problem is now that if inputCodeOne was incorrect the second time, inputCodeTwo doesn't matter. So you'll prompt for inputCodeTwo with no chance of success.
On lines 103, 104 you type
correctPassTwo = false;
if(!correctPassTwo) { }
If 104 is ever reached, 103 will have been reached as well, so the assignment of false and the conditional are unnecessary.
Again if inputCodeOne was incorrect twice, this code block is unnecessary. You're now prompting the user to give the second code twice, with no chance of success occurring. Because inputCodeOne is still wrong.
With loops you could do something like this:
Ask for inputCodeOne as many times as you'd like, until it's correct or until the limit is reached.
If the limit is reached, print "ACCESS DENIED" and end program.
If the password is correct, you can go onto the inputCodeTwo.
Same thing, ask for inputCodeTwo as many times as you'd like.
If the two codes match, print your password correct message.
Otherwise, after a certain number of attempts, you can terminate the program.
You can do that with 25% of the initial code.

C++: goto and user input not working together

I am working on C++, and using a basic authentication method using if statements, so what I have here, is when the the input is not the desired combination, it will say Access denied and ask the user if they want to try again or quit. I tried doing this using the goto variable, but it hasn't been working. Help please? (Full code: https://pastebin.com/49LdGgJX)
else {
cout << "Access denied..." << " Try again? (Y/N) >" << flush;
string ask;
cin >> ask;
if(ask == "N" || "n"){
cout << "Shutting down..." << endl;
goto end;
}
else if(ask == "Y" || "y"){
goto restart;
}
else {
cout << "Invalid option." << endl;
goto restart;
}
}
end:
return 0;
Your if statements are wrong as:
if(ask == "N" || "n")
always evaluates to true because the "n" operand always evaluates to true and you are using a logical OR operator. The string literal of "n" decays to const char* pointer whose value is not 0 thus evaluating to true. What you want is:
if(ask == "N" || ask == "n")
and:
else if(ask == "Y" || ask == "y")
That being said don't use goto.
One of the possible break-ups of that code structure into more procedural way (wouldn't dare to call this "object oriented").
You can use similar way to break up menu handling code into separate functions for each option, etc.
If this would be multi-user app, then you may want to store instead of simple true/false full credentials of the user authenticated, like having a structure containing name, code (password probably can be thrown away after authentication to not keep it in memory long, if you don't need it later).
// returns true if user wants to exit
// sets authenticated to true when the Drew user is detected
bool AuthenticateUser(bool & authenticated) {
cout << "Enter your username >" << flush;
...
if (name == "Drew" && ...) {
authenticated = true;
cout << "Access granted. Welcome, " << name << "." << endl;
cout << "Welcome to Database of Drew" << endl;
return false;
}
cout << "Access denied..." << " Try again? (Y/N) >" << flush;
...
return (ask == "N" || ask == "n"); // N = wants to exit
}
// returns true if user wants to exit
bool ProceedWithMenu() {
cout << "1.\tAdd new record." << endl;
cout << "2.\tDelete record." << endl;
...
if (1 == value) {
...
}
if (5 == value) {
cout << "Application quitting... " << endl;
}
return (5 == value);
}
void mainLoop {
bool authenticated = false;
bool exitApp = false;
do {
if (!authenticated) {
exitApp = AuthenticateUser(authenticated);
} else {
exitApp = ProceedWithMenu();
}
// repeat authentication / menu until user decides to quit app
} while (!exitApp);
}
This example is still quite crude and oversimplified, just trying to illustrate power of do {} while, return, and similar. Often also continue and break can be of great help to control the flow of code execution, without any goto and labels.

Stuck in an infinite loop when validating user input as an int

So I'm displaying a menu using a do while loop as shown below, and I want the user to be prompted with the menu until they make a valid selection- by entering the digits 1, 2, 3 or 4. I then want to use a switch case statement for identifying the users choice and executing the relevant block of code. When it comes to input validation though, how can I account for the user entering a letter instead of a numerical digit? The below code successfully continues to the next iteration to reprompt the user when they enter a letter, except that it enters a continuous loop.
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(!(cin >> selection)){
cout << "Please select an integer from 1-4." << endl;
cin.clear()
}
}while(selection != (1) or (2) or (3) or (4));
I've tried inserting the code below using istringstream to stream the users response from a string into an int inside the while loop as an alternative method to try solving the problem but to no avail.
string temp;
cin >> temp;
clearInputBuffer();
istringstream is(temp);
is >> selection;
UPDATED CODE - still getting an infinite loop (only when the user enters an alphabetic
character; integers behaveas expected)
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(std::cin >> selection){
cout << "Enter the new price: ";
}
else if(!std::cin.eof()){
cout << "Please select an integer from 1-4." << endl;
cin.clear();
}
}while(selection != 1 && selection != 2 && selection != 3 && selection != 4);
while(selection != (1) or (2) or (3) or (4));
is syntactically valid although you most probably wanted
while(selection != 1 && selection != 2 && selection != 3 && selection != 4);
Your original expression is equivalent to
while((selection != 1) || (2) || (3) || (4))
(2), (3), and (4) are evaluated to true, which makes your loop infinite, because anything || true is true.
If anyone should be wondering, yes, C++ allows writing and instead of && and or instead of ||, and not instead of !, etc. You have to "Disable Language Extensions" to see this on MSVC.
[update]
Another problem is that in case of a non-integer input, the variable selection stays uninitialized. In the else clase, give it a value of -1, for example.
The obvious approach is to actually check that the input was successful and if that is not the case deal with the error, e.g., write an error message, clear the stream, ignore the character or line, and try again:
if (std::cin >> selection) {
// do something with the good selection
}
else if (!std::cin.eof()) {
std::cin.clear();
std::cout << "invalid character ('" << char(std::cin.get()) << "') ignored\n";
}
Your code checks the stream and clears it but it doesn't extract the offending character. By the time you get to the check whether the selection is in range things are already bad and will stay that way.
You'd than go on and check the range. Your approach doesn't quite work as the logic or operator evaluates each individual element. One way is to check if the entered value is member of a specific rnage, e.g., using
int const valid[] = { 1, 2, 3, 4 };
if (std::end() == std::find(std::begin(valid), std::end(valid), selection)) {
std::cout << "chosen invalid selection (" << selection << ")\n";
}
The alternative of checking each selection individually may be viable for a small number of selection but isn't really viable when the range of options grows bigger. Admittedly, once you have a bigger range of options you'd actually put the key and the operation together anyway:
std::unordered_map<int, std::function<void()>> actions;
bool done = false;
// set up different operations for the respective actions, e.g.:
actions.insert(std::make_pair(1, [](){ std::cout << "hello, world\n"; }));
actions.insert(std::make_pair(2, [&](){ done = true; std::cout << "goodbye\n"; }))
int selection;
if (std::cin >> selection) {
auto it = actions.find(selection);
if (it != actions.end()) {
(it->second)();
}
else {
std::cout << "unknown action selection " << selection << '\n';
}
}
Try this
while(selection != (1) and selection != (2) and selection != (3) and selection != (4));
selection != (1) or (2) or (3) or (4)
Non-zero integers will evaluate to true so this is the equivalent of:
(selection != (1)) or true or true or true
which will always evaluate to true.
The way to fix this is to compare each individually
while(selection != 1 && selection != 2 && selection != 3 && selection != 4)
(2), (3, (4) are always true, that's why you are stuck in an infinite cicle. try:
while(selection != 1 && selection != 2 && selection != 3 and selection != 4);
A Shorter version:
while (selection <= 4 && selection >= 1)
I got it to work, the update provided in the original post was missing one extra line of code which I identified from sifting through other questions regarding validating input in a while loop. I think #Dietmar Kühl tried to illustrate something similar in his suggestion, however my compiler didn't like the code and I didn't quite understand it so I wasn't sure how to make it work. I'll be playing around with your suggestion regarding validating against a range though Dietmar so thank you for your input.
Thanks also to everyone who contributed to this thread, especially the 99% of you that did so without sounding condescending :-) There's always one though. The thread from which I identified my missing statement can be found here, and the line added to the code is identified with a comment in the code below. Thanks again!
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(std::cin >> selection){
cout << "Enter the new price: ";
}
else if(!std::cin.eof()){
cout << "Please select an integer from 1-4." << endl;
cin.clear();
cin.ignore(10000,'\n'); // this line eliminated the infinite loop issue
}
}while(selection != 1 && selection != 2 && selection != 3 && selection != 4);

Need help on reading a character from a string

My program is supposed to ask the user to input their credit card number and then display whether the numbers are valid or invalid and if valid ,display the card type. I'm having trouble trying to read the first 2 characters in the cardNumber string in order to find out whether the card type is visa,mastercard,american express or discover (4 for visa, 5 for mastercard, 37 for american express, 6 for discover)
#include <iostream>
#include <string>
using namespace std;
int main()
{
string cardNumber; //this will carry the number given by the user.
int sum(0), sumOfDoubleEven(0), sumOfOdd(0), evenDigit(0), oddDigit(0);
cout << "This program is the Credit Card Number Validator." << endl;
cout << "This program will check the validity status of your card number" << endl;
//Main loop
do
{
cout << endl << "Please provide a number to validate or type 'n' to quit ";
cin >> cardNumber; //gets cardNumber from user
if(cardNumber.length()>=13 && cardNumber.length()>=16)
{
if (cardNumber == "n") break; //exits loop on user request
//this for loop repeats once for each digit of the cardNumber.
//digitPosition decrements by one on each pass from last position to first position
for (int digitPosition=cardNumber.length(); digitPosition>0; digitPosition--)
{
if (digitPosition%2 == 0)
{ //executes the following code if digitPosition is even
oddDigit=(int)cardNumber[digitPosition-1]-'0';
sumOfOdd=sumOfOdd+oddDigit;
} else { //executes the following code if digitPosition is odd.
evenDigit=((int)cardNumber[digitPosition-1]-'0')*2;
evenDigit=evenDigit%10+evenDigit/10;
sumOfDoubleEven=sumOfDoubleEven + evenDigit;
}
}
sum=sumOfOdd+sumOfDoubleEven; //sums the result
cout << endl <<"The number "<<cardNumber<<" you provided is ";
if (sum%10==0) //executes if sum is divisible by 10
cout << "valid" << endl;
else //executes if sum is not divisible by 10
cout << "invalid" << endl;
if(cardNumber.at(0)==4) {
cout<<"Your Card type is VISA"<<endl;
} else {
cout<<"Sorry, you've entered a card number not in the range of 13-16 digits" <<endl;
}
}
}while (cardNumber != "n");
return 0;
}
There are some odd parts in your code, but the problem is you are testing the first digit against a number while your digit is stored in a string. So the test should be if (cardNumber.at(0) == '4') ....
One of your problems is that you get the first character (at position 0) and compare it to an int. The value of a character, while an integer, is the value the character have in the current encoding. For example, in ASCII encoding (which is the most common) the character '4' has the value 52.
So that's why the comparison cardNumber.at(0)==4 will fail, because 4 is not equal to '4'.
if (cardNumber[0] == '4') {
// VISA
} else if (cardNumber[0] == '5') {
// mastercard
} else if (cardNumber[0] == '6') {
// discover
} else if (cardNumber[0] == '3' && cardNumber[1] == '7') {
// American Express
} else {
// Invalid card type
}
By the way, your card number length verification condition is not what you expect, it should be
if (cardNumber.length() >= 13 && cardNumber.length() <= 16) {...}

using user input such as YES and NO to control program flow in C++

I'm making a small program that uses a if else statement, but instead of using numbers to control the flow i want to be able to make the control work with with yes and no;
for example:
cout << "would you like to continue?" << endl;
cout << "\nYES or NO" << endl;
int input =0;
cin >> input;
string Yes = "YES";
string No = "NO";
if (input == no)
{
cout << "testone" << endl;
}
if (input == yes)
{
cout << "test two" << endl;
//the rest of the program goes here i guess?
}
else
{
cout << "you entered the wrong thing, start again" << endl;
//maybe some type of loop structure to go back
}
but I can't seem to get any variations of this to work, i could make the user type a 0 or 1 instead but that seems really stupid, i'd rather it be as natural as possible, users don't speak numbers do they?
also i need to be able to simply add more words, for example "no NO No noo no n" all would have to mean no
hopefully that makes some sense
also i would love to make this using a window but i've only learned basic c++ so far not even that and i cant find any good resources online about basic windows programming.
You're not reading in a string, you're reading in an int.
Try this:
string input;
instead of
int input = 0;
Also, C++ is case-sensitive, so you can't define a variable called Yes and then try to use it as yes. They need to be in the same case.
btw, your second if statement should be an else if, otherwise if you type in "NO" then it will still go into that last else block.
First of all, input must be std::string, not int.
Also, you've written yes and no wrong:
v
if (input == No)
// ..
// v
else if (input == Yes)
^^^^
If you want your program to work with "no no no ..", you could use std::string::find:
if( std::string::npos != input.find( "no" ) )
// ..
The same with "Yes".
Also, you could do this to be almost case-insensitive - transform the input to upper-case letters (or lower, whatever ), and then use find.This way, yEs will be still a valid answer.
bool yesno(char const* prompt, bool default_yes=true) {
using namespace std;
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
}
string line;
if (!getline(cin, line)) {
throw std::runtime_error("yesno: unexpected input error");
}
else if (line.size() == 0) {
return default_yes;
}
else {
return line[0] == 'Y' || line[0] == 'y';
}
}
string input;
cin >> input;
if (input == "yes"){
}
else if (input == "no"{
}
else {
//blah
}