C++ Blackjack code only going to first if statement - c++

I'm trying to code a blackjack game and everything is going smoothly so far but for this bit. No matter what I input into hitStand it always goes to the first if statement and "hits". I would like for if "h" is inputted it "Hits" and if "s" is inputted it "Stands" and, if there is an invalid input, it will tell the user to try again.
I'm still fairly new to C++, so some help would be appreciated.
while (repeat == 0)
{
char hitStand;
cout << "Would you like to HIT or STAND [H/S]";
cin >> hitStand;
if (hitStand = "H" || "h")
{
PcardNew = rand() % 13 + 1;
cout << endl;
cout << "Your new card is: " << PcardNew << endl;
if (PcardNew > 10)
{
PcardNew = 10;
}
playerTotal = playerTotal + PcardNew;
cout << "Your new total is: " << playerTotal << endl;
}
else if (hitStand = "S" || "s")
{
break;
}
else
{
cout << "Please enter a valid imput [H/S]" << endl;
}
}

There are (at least) three errors in the single if (hitStand = "H" || "h") line!
First, the = operator is an assignment, not a comparison; to test for the equality of two operands, you need the == operator.
Second, the "H" and "h" constants are string literals - that is, multi-character, null-terminated strings of characters. Use single quotes for single characters (thus, 'H' and 'h').
Third, you can't compare one object with two others like that with a logical or (||) operator. You need to make two separate comparisons and then or the results of each:
So, use this:
if (hitStand == 'H' || hitStand == 'h')
{
//...
And similarly for your second test:
else if (hitStand == 'S' || hitStand == 's')
{
//...

That is because your condition in if statement is always true. Since "h" is in or (||).
Instead use:
if (hitStand == 'H' || hitStand == 'h')
and
else if (hitStand == 'S' || hitStand =='s')

Related

Input not being read properly by if condition statement

one would think this is easy, but for some odd reason, my conditional statement is ignoring user input.
If I input a character 'N' or 'n' it still executes the 'Y' portion of the conditional statement, have a look:
while (i < 10) {
cout << "Would you like "<< nameOfDish[i] << "? Please enter Y or N.\n";
cin >> userResponse;
if (userResponse == 'y' || 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
else if (userResponse == 'n' || 'N')
{
i++;
}
else
{
cout << "I think you mumbled NO, so I'll just go on.\n";
i++;
}
}
Is there any particular reason why despite inputting 'n' it still goes into the 'Y' if conditional block?
I have stepped through the code in the debugger, and I noticed that the userResponse variable is being read in properly. Yet, the if condition does not seem to be working properly. Thanks!
This statement (and your other if statement) is not doing what you think it does:
if (userResponse == 'n' || 'N')
Try this instead:
if (userResponse == 'n' || userResponse =='N')
You need to define each logical operation individually in a condition check. You will have to compare userResponse with n and N separately.
if (userResponse == 'y' || userResponse == 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
It's been awhile since I worked in C++, but I'm fairly sure I know what's going on.
The || operator does not work on a single conditional, there must be two complete conditionals, one on each side. Try replacing your if statement with this line:
if (userResponse == 'y' || userResponse == 'Y')
Maybe you are used to SQL? You need to repeat the userResponse
if userResponse == 'n' || userResponse == 'N'
Otherwise you are actually testing
if userResponse is 'n' or the char'N' exists
The error in this code is, as others have pointed out, the if statement. However, I feel this may need some clarification. Every C++ expression returns a value. For example.
userResponse == 'y'
returns the value 1 if userResponse is 'y' and 0 if it is anything else. The operator || returns 1 if either the left or the right expression is non-zero.
Finally, the if statement checks to see whether or not the expression is zero or non-zero. So,
if (5)
cout << "X";
else
cout << "Y";
will print X and
if (0)
cout << "A";
else
cout << "B";
will print B.
Now, we can begin to understand why your code compiled successfully, but didn't do what you wanted it to.
if (userResponse == 'y' || 'Y')
In this example, the || operator will always return 1 because the expression on the right, 'Y', will always be non-zero (specifically, it will be 89, since C++ characters are just aliases for their ASCII corresponding number). And of course,
if (userResponse == 'y' || userResponse == 'Y')
work as intended. But there is a much better solution and that would be the switch statement, whose purpose is to handle situations like this. Here it is in action:
switch (userResponse) {
case 'y':
case 'Y':
//The user answered yes, handle that situation here.
break;
case 'n':
case 'N':
//The user answered no, handle that situation here.
break;
default:
// The user did not enter a valid answer,
// handle that situation here.
break;
}

How to take a word from a file, and store it in a variable? C++

I have made a simple Rock, Paper, Scissors game in C++ Console Application. The game so far, worked great.. until I tried storing a word from a file, inside a variable, and then trying to use that variable in IF statements.
Here's how I store my word from the file, in a variable.
string comp_selection;
char player_selection;
And here's the part of the code where I am trying to get it to work.
cout << "Rock, Paper, or Scissors?";
cin >> player_selection;
if (comp_selection =='r' || comp_selection == 'R')
{
if (player_selection == 'r' || player_selection == 'R')
{
cout << "Computer chose " << comp_selection << "... It's a draw!" << std::endl;
}
else if (player_selection == 'p' || player_selection == 'P')
{
cout << "Computer chose " << comp_selection << "... You win!" << std::endl;
}
else if (player_selection == 's' || player_selection == 'S')
{
cout << "Computer chose " << comp_selection << "... You lose!" << std::endl;
}
}
The output should be:
Computer chose Rock... You win!
If the player chose Paper for example.
Instead, I get this error message
Severity Code Description Project File Line Suppression State
Error C2678 binary '==': no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
Any help or guidance, would be great! Many thanks in advance.
Your comp_selection is defined as a std::string, but you are comparing it against a char ('r', etc). You should compare it against another string ("r") or just redefine comp_selection to be a character:
char comp_selection;
char player_selection;
In C++, a single character is denoted by single quotes ('c') whereas a string of characters is denoted by double quotes ("full string").
So far, you have been enjoying cin >> overloading recognizing that it's writing to a char. When reading from a file, you've apparently utilized a string. This is fine, except now the compiler is complaining that it does not know how to compare a string and a char. In short, your types don't match.
You can compare only first character of comp_selection (comp_selection[0])
if (comp_selection[0] =='r' || comp_selection[0] == 'R')
{
It is not the best solution but it requires the minimum code changes...
I've just realised that my code does what it was intended to do! By setting my
comp_selection to char, like someone here suggested, I can manually input what the computer chose by using the IF Statements.
For example:
if (comp_selection == 's' || comp_selection == 'S')
{
if (player_selection == 'r' || player_selection == 'R')
{
cout << "Computer chose Scissors... You win!" << std::endl;
}
else if (player_selection == 'p' || player_selection == 'P')
{
cout << "Computer chose Scissors... You lose!" << std::endl;
}
else if (player_selection == 's' || player_selection == 'S')
{
cout << "Computer chose Scissors... It's a draw!" << std::endl;
}
}

Unable to compare characters (c++)

I'm trying to make a simple mad libs program in c++, and i want to check and see if a word that a user entered starts with a vowel, and if it does, change the "a" before the word, to an "an". I've been able to get the first character stored, but it will not compare to the other characters in the If statement. Am i doing this completely wrong?
#include <string>
#include <iostream>
using namespace std;
int main() {
string adj_3;
string anN;
char firstChar;
// GETTING USER'S WORD
cout << "ADJECTIVE: " << endl;
getline(cin, adj_3);
// GETTING FIRST CHARACTER
firstChar = adj_3[0];
// SEEING IF IT'S A VOWEL (not working)
if(firstChar == ('a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'E' || 'I' || 'O' || 'U')) {
anN = "n";
}
else {
cout << "not working" << endl;
}
cout << "I am having a" << anN << " " << adj_3 << " time at camp." << endl;
}
The || operator needs to be applied to two arguments, like so:
if (firstChar == 'a' || firstChar == 'e' || firstChar == 'i' || ...)
firstChar == 'a' evaluates to a boolean. firstChar == 'a' || firstChar == 'e' takes the two booleans that results from those two operations, and returns another boolean, which is then fed into the next || operation as the first argument. In this way you can "chain" the || operations until one of them is true, or until they're all false.
See here for examples and explanation.
hnefatl's answer is one way.
You can also use switch case without break statements to check vowel. Something like:
switch(firstChar)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U': cout<<"Vowel";
}
On top of that switch-case have many advantages over if-else ladder as stated here https://stackoverflow.com/a/1028463/6594779.
Logical operator || combines two boolean expressions, e.g. a==0 || b==1, and returns true if either of the two operands is true. If you pass a single character like 'a' as operand, this will be interpreted as true, since the value of 'a' is 97 and 97 != 0 => true. Hence, your expression ('a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'E' || 'I' || 'O' || 'U') will always be true, and firstchar == (....) is the same as firstchar == true, which will probably give false.
You could write...
if (firstChar == 'a' || firstChar == 'e' || firstChar == 'i' || ...)
or...
if (strchr(firstChar, "aeiouAEIOU") != NULL)) ...
You can use an array too wherein you store all the vowels and then compare it. Something like shown below:
char vowels[10]={'a','e','i','o','u','A','E','I','O','U'};
int flag=0;
for(int i=0;i<10;i++)
{
if(vowels[i]==firstChar)
{
flag=1;
anN="n";
}
}
if(flag==1)
cout << "I am having a" << anN << " " << adj_3 << " time at camp." << endl;
else
cout << "not working" << endl;

how to only allow 3 values in a "if" and "while" statement to allow the loop to exit

I'm just stuck on some logic statements.
specifically the ones that are in the function char GetInteger() so how would I only allow 3 values to cause the loop to exit.
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (usrinput != 0 || usrinput != 1 || usrinput != 2)
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(usrinput != 0 || usrinput != 1 || usrinput != 2);
return userInput;
}
Two issues with this code:
First userinput has a type of char. So when you read from a stream you read a single character (after dropping white space). So when a user types 1<enter> you get the character '1' in the variable userinput. Note the character '1' is not the same as the number 1.
Thus your test should be:
userinput != '1';
Secondly your boolean logic is wrong. When first learning it is sometimes easier to state the problem as a list of values that you would like to be acceptable (not the unacceptable ones).
You want the conditions to be false if the userInput has one of your accepted values (any good value will fail the test and thus not invoke the bad code). The first step to this is to get a true if any of your values are valid.
// If any value is good then true.
userinput == '1' || userinput == '2' || userinput == '3'
To invert this just add a not to the expression.
if (! (userinput == '1' || userinput == '2' || userinput == '3') )
Note: in boolean logic
!(A || B) => (!A && !B)
So you could re-write the above as:
if (userinput != '1' && userinput != '2' && userinput != '3')
I think this was your main mistake you converted the == into != but did not convert the || into &&.
I would also suggest that you could simplify this (as you may get more valid result) byconverting this into a range based test.
if (userinput < '1' || userinput > '3')
{
// Test Failed.
}
Additionally. Since you have the test in two places. You should yank it outinto its own function. Then you can call the function to do the test.
bool isUserInputValid(char userInput)
{
return userInput >= '1' && userInput <= '3';
}
Now we can re-write your original function as:
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (!isUserInputValid(userinput))
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(!isUserInputValid(userinput));
return userInput;
}
First of all, you should use int instead of string as you are reading integer.
You can use while(1) instead of putting condition in while. Inside while loop, if your selection is 0 or 1 or 2, you can simply break the loop.

C++ do/while loop with two different conditions

I want the do while loop to check to see if the entered input is R OR P. I think it is checking for both and when I get to that part when I run, it pauses for a minute and then I get "CPU Limit Exceeded (core dumped). On another related note, am I in danger of breaking something?
/************************************************/
/* Name: servcode */
/* Description: Get service type */
/* Parameters: N/A */
/* Return Value: servcode */
/************************************************/
char servcode()
{
char servcode = 'a'; // Define variable for service code
char serviceyn = 'n'; // Define variable for user verify
int i = 1; // Define variable for sentinel loop
do {
cout << "\n" << "\n" << "Please enter your service code, [R]egular or [P]remium: " << "\n";
cin >> servcode;
while ((servcode != 'R', 'P') && (i < 3));
{
cout << "\n" << "Error - invalid service code, please try again.";
cout << "\n" << "Please enter your service code: ";
cin >> servcode;
i++;
if (i == 3)
{
cout << "\n" << "Too many invalid attempts, program terminating." << "\n"
<< "Have a nice day. " << "\n" << "\n";
exit (0);
} //end if
} //end while
cout << "\n" << "You entered: " << servcode << "\n"
<< "Is that correct? [y,n]";
cin >> serviceyn;
} while (serviceyn != 'y'); // end do/while loop
return servcode;
}
The correct syntax is:
while (servcode != 'R' && servcode != 'P' && i < 3)
Note the expanded comparison and the removal of the semicolon at the end:
(servcode != 'R', 'P') is valid C++ but doesn't do what you're expecting it to do;
the semicolon makes the statement into a loop with an empty body, so it continues executing forever since the loop condition never changes.
Change:
while ((servcode != 'R', 'P') && (i < 3));
to:
while ((servcode != 'R') && (servcode != 'P') && (i < 3))
Note the removal of an unwanted semicolon.
You need to do something like this:
while(something != 'a' && something != 'b')
You're using the comma operator, which discards the results of every expression except the last, so this:
while(something != 'a', 'b')
Will compare something with a, ignore the result, and use 'b' as the condition of the loop. 'b' is a non-zero value, so it's always true and the loop goes on forever (or until memory runs out, or something else stops it).
(servcode != 'R', 'P')
Should be:
(servcode != 'R') && (servcode != 'P')
Kudos to PaulR for correction. My brain is not in gear.
Let's break down this statement and see what it's doing. I've put in some extra punctuation that does not change the meaning of the statement.
while (((servcode != 'R'), ('P')) && (i < 3)) { };
The comma operator separates two different expressions and returns the value of the second one. The first part probably does what you expect, but the second part is just a literal character 'P' which is always true!
The semicolon at the end of the statement marks the body of what will be executed as the while loop. It's a do-nothing which does not change the value of servcode or i, so obviously once you enter the loop you will never leave it. This is a common mistake.