Issues with IF statement - c++

The application asks the user to enter the students major - either math or CIS and I wanted to make it so if the user were to enter something other than those two it would give an error message and prompt the user to enter the major again.
Here is what I have so far:
cout << "Math or CIS Major: ";
cin >> major;
if (major != "math" || major != "Math" || major != "CIS" || major != "cis") {
cout << "Invalid major" << endl;
}
cout << "Enter students GPA: ";
cin >> studentGpa;
This will give the invalid major message but it will just move onto the GPA
For some reason I can't remember the basics and this is tripping me up.
Also if someone could guide me in the right direction for an alternative to the ||'s I know this isn't the best way to do this but again I am struggling with coming up with a better way to do this again

Replace OR(||) with AND(&&)
if (major != "math" && major != "Math" && major != "CIS" && major != "cis")

If you want the user to have to input a valid major then you need to put it into a loop:
std::string major;
std::cout << "Major: ";
std::cin >> major;
while (major != "math" && major != "Math" && major != "CIS" && major != "cis")
{
std::cout << "Please enter a valid major!\n";
std::cout << "Major: ";
std::cin >> major;
}
This way the program will not continue unless they enter a valid major.

You are confused between OR (||) and AND (&&). Replacing || by && in the IF condition should do the trick.
What your current if statement checks (if A is not equal to B) OR (if A is not equal to C). If B and C are distinct, then A can at max be equal to one of them, or in other words, will always not be equal to at least one of them.
So, your condition will always evaluate to true. The correct term for this is that your if condition is a tautology.
If you want to skip all this and want the code:
if (major != "math" && major != "Math" && major != "CIS" && major != "cis") {

Related

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++ Loops & Boolean Expressions

I have an assignment for my Intro to Comp Sci course at college. We are told to use only Loops & Boolean Expressions to create the program.
Here is a link to the assignment sheet directly:
http://cs.saddleback.edu/michele/Teaching/CS1A/Assignments/AS8%20-%20Boolean%20Expressions.pdf
I got it working with a bunch of If, Then, Else statements until I read the directions again and had to change it.
I got the 'm' 'f' 'M' 'F' part to work, but I can not get the heightOK or the weightOK (directions #2 and #3) to work out.
Please help, thanks!
PS I am brand new to programming...
Here is what I have so far: `
char gender;
int weight;
int height;
bool heightOK;
bool weightOK;
cout << "Please enter the candidate’s information (enter ‘X’ to exit).";
cout << "Gender: ";
cin.get(gender);
cin.getline(100 , '\n');
if (gender == 'm' || 'M' || 'f' || 'F')
{
}
else
{
cout << "***** Invalid gender; please enter M or F *****";
}
cout << "Height: ";
cin >> height;
cout << "Weight: ";
cin >> weight;`
You can do this without if statements. You should use do-while loops for each input, such that you loop while the input is invalid. Then, you can set your bool variables like this:
heightOK = ((gender == 'm' || gender == 'M') &&
(height > MALE_TOO_SHORT && height < MALE_TOO_TALL));
heightOK = (heightOK || (/*same as above, female version*/));
You could do that all in one line, but that gets hard to read, IMO. You should be able to set weightOK the same way.
EDIT: The do-while loop asks for and gets the input. Then, the while statement tests the input for validity.
do {
cout << "enter gender (m/f)";
cin >> gender;
} while ( !(gender == 'm' || gender == 'M' || gender == 'f' || gender == 'F') );
If you want to tell the user that the input is invalid, you can use a while loop after getting the input the first time.
Here's the expression showing that the ternary operator is a valid Boolean function with respect to
(p ∧ q) ∨ (¬p ∧ r)
"(p and q) or ((not p) and r))" or "if p then q, else r"
See also: http://en.wikipedia.org/wiki/%3F:, http://en.wikipedia.org/wiki/Conditioned_disjunction
Full disclosure, I didn't read the assignment. I just saw the implication in your post that you're restricted from using "if then else" statements and thought I'd offer a creative way to cheat.

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

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.

Allowing multiple types of input for various forms of "yes" and "no" in C++

I posted a question about how to get user input such as YES or NO to control the flow of a program using if else statements, I got a answer and now i'm a step closer to making this work, however another problem has arisen, i really need to allow for multiple inputs, for example this is what im trying:
if (input == ("YES" || "yes" || "y" || "Yes" || "Y"))
{
cout << "you said yes" << endl;
}
else if (input == "NO", "no", "n", "No","N")
{
cout << "you said no" << endl;
}
else
{
cout << "ERROR!!!" << endl;
}
Kiril Kirov posted this code that could help:
if( std::string::npos != input.find( "no" ) )
but i couldn't get it to work, and roger pate suggested this:
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
however i never tried this as its complexity is far beyond my understanding. i was hoping for a solution a beginner programmer could understand or maybe im just a really slow learner
EDIT:
I made this modification but it still doesn't work any better then before, if i give the wrong case it goes to else (error) and there is no where to add more words, (such as NO N no No) :
cout << "\nYES or NO" << endl;
string input ="";
cin >> input;
if ( std::string::npos != input.find( "yes" ) )
{
cout << "you said yes" << endl;
}
else if ( std::string::npos != input.find( "no" ) )
{
cout << "you said no" << endl;
}
else
{
cout << "ERROR!!!" << endl;
}
Add the headers
#include <algorithm>
#include <cctype>
cout << "\nYES or NO" << endl;
string input ="";
cin >> input;
transform (input.begin(), input.end(), input.begin(),tolower);
if ( (std::string::npos != input.find( "yes" )) || (std::string::npos != input.find( "y" )) )
{
cout << "you said yes \n" ;
}
else if ( (std::string::npos != input.find( "no" ) ) || (std::string::npos != input.find( "n" ) ) )
{
cout << "you said no \n" ;
}
else
{
cout << "ERROR!!! \n" ;
}
In most languages the easy way is to uppercase the string before comparing it.
In standard C++ uppercasing is, unfortunately, more complex. It has to with very heavy resistance to having any new feature that doesn't work perfectly in every conceivable case. And uppercasing is a feature that by it's nature -- different in different countries, sometimes even context-sensitive -- cannot work perfectly in every conceivable case.
Adding to that, the C library's uppercase function is a bit difficult to use correctly.
Dang, I'd give you a reasonable uppercase function right here but no time. :-( Search for earlier questions on uppercasing. That should work! :-)
Cheers,
The simpler way is to convert the case beforehand. Assuming that the user restricts its input to one of the valid strings (yes/no).
Check out Boost.String, it's a collection of algorithms on the std::string class (and specifically here case conversions routines).
It'll work great for ASCII characters, but since we're talking of std::string that should be okay, you're not planning on handling japanese or arabic are you :) ?
How about you just check first two characters of the string and see if they are n N or Y y?
I haven't used C++ strings in a while, but there are several functions which look interesting. Take a look at this site. You could for example take length of a string. Then you could take characters at positions zero, one and if available two using functions I liked to. After that see if the first character is Y,y, N, n. You could go on if you want to be even more sure that user hasn't inputted nonsense (if first letter is N or n check if second in O or o and so on), but I think that this should be enough for simple decision.