C++ code, bools, and loops - c++

I am new to C++ programming and haven't done anything in a week, so I was messing around with things I know thus far to see if I have to go over things again.
However, I ran into an issue with bools (haven't really used them before).
Source:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
signed long int x;
unsigned short int y = 12345;
bool POSX;
bool yes;
cin >> x;
if (x >= 0)
{
POSX = true;
}//end of if for bool
else
{
POSX = false;
}
cout << "This is the current value of X: " << x << endl;
if(x < y)
{
cout << "x is less than the integer y \n \n";
}//end of if
else
{
cout << "y is greater than the integer x \n \n";
}//end of else
cout << "The current value of Y is: " << y << endl << endl << endl;
cout << "Is X positive?: " << POSX << endl << endl;
cout << "How much more would X need to be to surpass y? The answer is: " << y - x << endl;
if(x > y)
{
cout << "well, actually, x is greater than y by: " << y - x << " so you would need to add that to get to the value of x" <<endl <<endl;
}//end of if
cout << "Do you like cookies? Enter below. . ." <<endl;
cin >> yes;
if(yes = "yes") // should this be if(yes = 1)?
{
cout << "I do too! But only when they are soft and gooey!";
} //end of if for bool yes
else
{
cout << "Well, join the dark side, and you may be persuaded by the power of cookies and the power of the dark forces!";
}//end of else for bool yes
char f;
cin >> f;
return 0;
} //end of main
The issue I have is when I try to compile, for one, the program exits before I can see the result of the cookie question [so I have to place a break point in the compiler], and second, when I can see the answer, it always comes up with the yes response, and not anything else.
So, if I put no as the input, it still outputs the if for the bool yes being true. I am not sure if I am defining the if clause correctly in the last statement.
Could anyone help?

Ok, two things. Your major problem is this:
if(yes = "yes")
'yes' is definend as a bool type, i.e., it can hold the values "true" or "false". You attempting to compare comparing (actually attempting to assign due to using only one = instead of ==, which is how you check for equality) a boolean to a string "yes". Well, that makes no sense. It should be:
if( yes )
That's it. 'yes' is already a boolean, and the expression in an if statement requires no more.
Secondly, constructs like this are redundant and unnecessary:
if (x >= 0)
{
POSX = true;
}//end of if for bool
else
{
POSX = false;
}
You are checking for a boolean value and then assigning one. Just do it in one line like this:
POSX = (x >=0 );
Also, you typically don't use all caps for local variables.
One more thing; you are entering string data ("no" or "yes") and cin is expecting an int. I suggest that you spend some time learning about what data types are.

The issue I have is when I try to compile, for one, the program exits before I can see the result of the cookie question
That's because you invalidated cin when you put "no" as the value. operator>>(std::istream&, bool&) assumes numeric input. Values not equal to zero will be interpreted as true, and values equal to zero will be interpreted as false.
If you supply input that cannot be parsed as numeric badbit will be set on the stream. Attempting to use the stream while it is in this failed condition will result in garbage being read (or rather, undefined behavior), and no advancement of the get pointer in the stream.

Change yes to a string(#include <string>), and then compare it like this:
if (yes == "yes")

There are a couple of things going wrong here, but I think the one tripping you up is cin >> yes; In C++, false is 0. Therefore, this will likely return true for any non-zero input values. A more reliable approach would be to ask for and evaluate on something else, for instance, character input:
cout << "Do you like cheese? (y/n) ";
char c;
cin >> c;
if ( c == 'y' || c == 'Y' )
do whatever;
Additionally, when testing conditionals, be sure to use "double-equals", condition == true. Better yet, adopt the shorthand where:
(condition) means (condition == true)
(! condition) means (condition == false)
Hope that gives you a start in the right direction.

Here is the edited sources code, I made changes so study it and compare with the original code. *e*
#include <iostream>
#include <string>
#include <iomanip> //headerfile for boolalpha
using namespace std;
int main()
{
string answer;
signed long int x;
unsigned short int y = 12345;
bool POSX;
bool yes;
cout<<"Enter any value: ";
cin >> x;
if (x >= 0)
{
cout << boolalpha; // print bools as true or false
POSX = true;
}//end of if for bool
else
{
cout << boolalpha; // print bools as true or false
POSX = false;
}
cout << "This is the current value of X: " << x << endl;
if(x < y)
{
cout << "x is less than the integer y \n \n";
}//end of if
else
{
cout << "y is greater than the integer x \n \n";
}//end of else
cout << "The current value of Y is: " << y << endl << endl << endl;
cout << "Is X positive?: " << POSX << endl << endl;
cout << "How much more would X need to be to surpass y? The answer is: " << y - x << endl;
if(x > y)
{
cout << "well, actually, x is greater than y by: " << y - x << " so you would need to add that to get to the value of x" <<endl <<endl;
}//end of if
cout << "Do you like cookies? Yes/No. . ." <<endl;
cin >> answer; //this is a string
if(answer =="yes") // it can be a simple if statement
{
cout << "I do too! But only when they are soft and gooey!";
} //end of simple if
else
{
cout << "Well, join the dark side, and you may be persuaded by the power of cookies and the power of the dark forces!";
}//end of else for simple if
return 0;
} //end of main`

Related

How do I keep asking the user a question over and over again until they enter the correct field of value?

I am a rookie coder here and I can't seem to figure out what to add to my code here to get it right. It is supposed to ask the user again if they do not answer the question "Do you want to make another calculation Y or N?" correctly. I want it to repetitively ask the user to enter y or n if they enter something else. I feel like it is obvious I am just missing it. This is for school, to be clear.
I've tried nesting a do while loop and an if statement but only to get run time errors
#include <iostream>
using namespace std;
int main() {
int base, exponent;
long int result = 1;
char choice;
int i;
do
{
cout << "This program raises a number to a specific power." << endl;
cout << "\nEnter a base integer greater than 1: ";
cin >> base;
cout << "\nEnter an exponent integer to raise that number to: ";
cin >> exponent;
for (i = 1; i <= exponent; i++)
{
result = result * base;
}
cout << "\n" << base << " to the power of " << exponent << " = " << result << endl;
result = 1;
// ***** HERE IS WHERE I NEED HELP, WHAT TO
// DO IF THEY DONT ENTER Y OR N.....
cout << "\nWould you like to make another calculation? Y or N: ";
cin >> choice;
cout << endl;
}
while (choice == 'y' || choice == 'Y');
cout << "Good bye, then. Have a good day.\n" << endl;
return 0;
}
When I tried adding a nested do while loop, and entered a character answer other than y or n, it would go to a part of the program it should not have.
*this is my first question so I hope I've done this correctly
You can use another do-while loop to wrap the input section.
do
{
cout << "This program raises a number to a specific power." << endl;
cout << "\nEnter a base integer greater than 1: ";
cin >> base;
cout << "\nEnter an exponent integer to raise that number to: ";
cin >> exponent;
for (i = 1; i <= exponent; i++)
{
result = result * base;
}
cout << "\n" << base << " to the power of " << exponent << " = " << result << endl;
result = 1;
do
{
cout << "\nWould you like to make another calculation? Y or N: ";
cin >> choice;
cout << endl;
} while (choice != 'y' && choice != 'Y' && choice != 'n' && choice != 'N');
}
while (choice == 'y' || choice == 'Y');
Learn to think organically here. Let me do a procedural approach.
We begin by bringing your formulations into a more technical form, until it is syntactically and semantically working. Let's start by transforming it into this:
void process_things()
{
...
while(still_require_answer)
{
ask_for_answer();
}
...
}
This is very close to how you formulate it verbally, yes? Now, let's flesh it out.
string ask_for_answer(bool& still_require_answer);
void process_things()
{
...
string answer = "";
bool still_require_answer = true;
while(still_require_answer)
{
answer = ask_for_answer(still_require_answer);
}
...
}
// hope you understand the concept of a reference here,
// that is what the ampersand (&) does, if not, ask
string ask_for_answer(bool& still_require_answer)
{
string answer = ""; // always initialize
cout << "State answer: ";
cin >> answer;
cout << endl;
if(answer == "Y" or ...)
{
still_require_answer = false;
}
return answer;
}
Hope this helps you. In the long run, you might want to go OOP and use classes here. The code here is a little bit verbose, but orderly.
Note that I have put the routine in a new function process_things. Anything that is more than a few lines which you can name you should think about making a function (or a class method). Your main should be quite small. Cutting things down into smaller units helps you keeping thisng orderly and makes the design of each single unit easy (divide-and-conquer) and allows you to quicker locate problems as you can test every function separately (later, this leads to automated unit tests).
One could also take the while and put it into it's own function string ask_until_valid_answer();, and if we do that, dissolve ask_for_answer and put it's content there. What I want to focus on is to have it organically, that is use self-descriptive names which explain the program while reading it, and to cut the program into understandable units. Here would be this other layout:
string ask_until_valid_answer();
void process_things()
{
...
string answer = ask_until_valid_answer();
...
}
string ask_until_valid_answer()
{
string answer = "";
bool still_require_answer = true;
while(still_require_answer)
{
cout << "State answer: ";
cin >> answer;
cout << endl;
if(answer == "Y" or ...)
{
still_require_answer = false;
}
}
return answer;
}

input validation while loop is infinite

#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
double addition;
double subtraction;
double top, bottom;
double multiplication, multiplication2;
char variable;
double total = 0.0;
cout << "Type in:\n'A' For Addition\n"
<< "'S' For subtraction\n" << "'D' For division\n"
<< "'M' For multiplication\n";
cin >> variable;
switch (variable)
{
case 'A':
{
cout << "Enter 0 for input\n";
cin >> addition;
while(addition != 'Q' || addition != 'q')
{
cout << "Enter numbers for adding\nThen type in"
<< "Q or q to quit\n";
cin >> addition;
total += addition;
}
cout << "Your total is " << total << endl;
}
It loops infinitely starting out at the first cout statement in the while loop. I will type in numbers, then as soon as I type in q or Q and hit enter it will immediately loop infinitely. Thanks!
Your condition for the while loop uses a logical OR.
Let's say you try to quit the loop and enter the input 'Q'. The first part of the condition will be FALSE, but the second part of the condition will be TRUE. Since it is a logical OR, then the whole condition will be TRUE and the loop will execute. The converse is also true if you input 'q'.
So no matter what you enter, your loop will run.
There are two main problems in your program.
First, condition addition != 'Q' || addition != 'q' is always true, because for any value of addition, either addition != 'Q' or addition != 'q' is true (i.e. addition can never be both Q and q at the same time). You probably meant addition != 'Q' && addition != 'q'
Second, when you do cin >> addition with variable of type double, then you will either receive a valid number or - if somebody enters - 'Q', for example, "nothing" and an error flag is set. "Nothing" means that the value of addition remains unchanged.
To accomplish the "either a number or 'Q'"-thing, you need to read in a string and compare it to "Q" (or "q") and otherwise try to convert the string into a double.
The code fragment could look as follows:
int main() {
double sum = 0;
double toAdd;
std::string input;
bool end = false;
while (!end) {
cout << "enter a value to add (type Q or q to quit)" << endl;
cin >> input;
if (input == "Q" || input == "q") {
end = true;
}
else {
try {
toAdd = stod(input);
sum += toAdd;
} catch (out_of_range &e) {
cout << "input " << input << " is out of range." << endl;
} catch (invalid_argument &i) {
cout << "input " << input << " is not a valid number." << endl;
}
}
}
cout << "sum: " << sum << endl;
}

Having trouble with a 'while' loop in C++

I started building a very simple version of a calculator in C++. The idea is to perform basic operations with only two numbers and then loop back so the user can make a new calculation.
The program looks like this:
#include<iostream>
#include<string>
#include"mathOperations.h"
using namespace std;
int main()
{
int x, y;
string operation;
string repeat = "y";
while (repeat == "y" or "Y")
{
cout << "Welcome! This is a raw version of a calculator - only use two numbers." << endl;
cin >> x >> operation >> y;
if (operation == "+")
{
cout << "Result: " << add(x, y) << endl;
}
else if (operation == "-")
{
cout << "Result: " << subtract(x, y) << endl;
}
else if (operation == "*")
{
cout << "Result: " << multiply(x, y) << endl;
}
else if (operation == "/")
{
cout << "Result: " << divide(x, y) << endl;
}
else
{
cout << "This is not a valid sign. Please choose another one!" << endl;
}
cout << "Wanna go again? Type 'y' or 'n'." << endl;
cin >> repeat;
if (repeat == "n" or "N")
{
cout << "Alright, have a nice day!" << endl;
break;
}
}
}
int add(int x, int y)
{
return x + y;
}
int subtract(int x, int y)
{
return x - y;
}
int multiply(int x, int y)
{
return x * y;
}
int divide(int x, int y)
{
return x / y;
}
NOTE: There is a 'mathOperations.h' file in which I have made forward declarations of all functions used.
The problem is that whenever I type in 'y' to make it loop, it simply outputs the following 'if' statement and breaks out of the loop and the program finishes. I couldn't quite figure out why this is happening, since the 'if' statement is only supposed to run if I type in 'n'.
repeat == "n" or "N"
evaluates to
(repeat == "n") || "N"
see the C++ operator precedence.
The first repeat == "n" evaluates to true or false depending on your input, but the second clause of the OR, i.e. "N", always evaluates to true because it is a string literal that decays to a non-zero const char* pointer, and in C or C++ everything non-zero is implicitly converted to true. So your OR clause is always true, which implies that the if block will always be executed.
As mentioned in the comments, you need to do
if(repeat == "n" || repeat == "N") {...}
Similarly with the first while condition.
Nice code! I try using "||" in place of your "or" in your if statements. Might want to refresh your knowledge with C++ short-circuiting of booleans.

|| operator in while condition not working as expected

So I'm a new programmer and I decided to try and make this game. It is a basic, let's say person v. person game. You enter the amount of each team, in my case Ninjas and Samurai, and then it randomizes the attack chance of each and outputs the winner. Every time I run the program I input the number of each type, and I always get an output of the Ninjas having 0 health, and the Samurai having negative health. How would I be able to have the while loop end when one team gets to 0 health? I've tried using totalNinjaHealth != 0 || totalSamuraiHealth != 0 but the program runs infinitely.
#include <iostream>
#include <random>
#include <string>
#include <ctime>
using namespace std;
int main() {
int ninjas;
int NINJA_HEALTH = 2;
int NINJA_ATTACK = 2;
int samurai;
int SAMURAI_HEALTH = 3;
int SAMURAI_ATTACK = 1;
default_random_engine randomGen(time(NULL));
uniform_real_distribution<float> attackChance(0.0f, 1.0f);
cout << " *** Ninjas V Samurai *** " << endl;
cout << "Input amount of Ninjas" << endl;
cin >> ninjas;
cout << "Input amount of Samurai" << endl;
cin >> samurai;
int totalNinjaHealth = NINJA_HEALTH * ninjas;
int totalSamuraiHealth = SAMURAI_HEALTH * samurai;
cout << totalNinjaHealth << endl;
while (totalNinjaHealth > 0 == true || totalSamuraiHealth > 0 == true)
{
if (attackChance(randomGen) > 0.5f) {
totalSamuraiHealth -= NINJA_ATTACK;
cout << totalSamuraiHealth << endl;
}
else if(attackChance(randomGen) < 0.5f) {
totalNinjaHealth -= SAMURAI_ATTACK;
cout << totalNinjaHealth << endl;
}
}
if (totalNinjaHealth == 0) {
cout << "Ninjas lost all " << ninjas << " Ninjas. Samurai remaining " << totalSamuraiHealth << endl;
}
else if (totalSamuraiHealth == 0)
{
cout << "Samurai lost all " << ninjas << " Samurai. Ninjas that remain " << totalNinjaHealth / 2 << endl;
}
cin.get();
cin.get();
return 0;
}
Screenshot of what happens when ran:ConsoleWhenRan
Am I using the || operator incorrectly? I thought the || operator waits until one condition is true and then stops, but when I run the code It seems to wait until both either pass, or equal 0 giving the negative output.
You need to use the && operator. The || is the "or" operator and will evaluate to true when either one or both of the conditions are true. In your case, the while loop will continue to evaluate as long as one of your teams has health > 0. The "and" operator (&&) requires both conditions to be true for the statement to be evaluated as true.
What happens is:
You run the loop until either of the teams has positive total health. So the total health is for both of the teams is less/equal to zero.
Then you check the healths and you get your answer. It just so happens that in your case one of the teams died with exactly 0 health. In some cases though, the output should show neither the messages.

Conditional cin giving stacked cout messages

Using C++ (g++-4.7 on Mint 16).
Code is a unrefined (and unfinished) Tic-Tac-Toe game.
#include <iostream>
using namespace std;
int main()
{
//initial data
char turn='A';
char ttt[] = {'1','2','3','4','5','6','7','8','9'};
int move;
int over=0; //0 is no, 1 is yes
int valid=0;
while ( over == 0)
{
//display
cout << "\n" << ttt[0] << "|" << ttt[1] << "|" << ttt[2] <<"\n-----\n";
cout << ttt[3] << "|" << ttt[4] << "|" << ttt[5] <<"\n-----\n";
cout << ttt[6] << "|" << ttt[7] << "|" << ttt[8] <<"\n\n Choose a number (Player " << turn << "):";
//ask enter for play with turn
cin >> move;
cout << "\n";
valid = 0;
while (valid == 0)
{
//check if input is valid
if (((move > 0) and (move < 10)) and
((ttt[move-1] != 'A') and (ttt[move-1] != 'B')) and
(cin))
{
ttt[move-1] = turn;
valid=1;
}
else
{
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
}
//check if done if no //change turn then goto //display
if (((ttt[0]==ttt[1]) and (ttt[1]==ttt[2])) or
((ttt[3]==ttt[4]) and (ttt[4]==ttt[5])) or
((ttt[6]==ttt[7]) and (ttt[7]==ttt[8])) or
((ttt[0]==ttt[3]) and (ttt[3]==ttt[6])) or
((ttt[1]==ttt[4]) and (ttt[4]==ttt[7])) or
((ttt[2]==ttt[5]) and (ttt[5]==ttt[8])) or
((ttt[0]==ttt[4]) and (ttt[4]==ttt[8]))or
((ttt[2]==ttt[4]) and (ttt[4]==ttt[6])))
{
//display winner or say draw
cout << "Player " << turn << " wins!\n";
over=1;
}
else
{
//change turn
if (turn=='A')
{ turn='B';
}
else
{ turn='A';
}
}
}
return 0;
}
There seem to be a bug on the code. On the part where check if input is valid the and (cin) seem to be failing.
When entering a character, (Instead of a number) it output continuously stacks of:
Invalid slot. Choose a number (Player A or B):
I tested the rest of condition without it, it was all working well. Is there a problem on the code or is this really "cin" problem? I've also tried out !(!cin) but it's the same scenario.
You must clear the fail bit from the cin stream in your else block.
When you enter a character that isn't an integer, the cin stream sets the fail bit, which you correctly check for in your if statement, but you never clear it afterward. This causes your input validity check to be false forever.
#include <limits>
...
else
{
cin.clear(); // Add this line
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // And this one
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
For additional information, see the documentation for std::basic_ios::clear
Update: see this question and this question for similar problems.
Essentially, you also need to tell cin to ignore whatever is in the stream or it will continually set the fail bit with its bad contents you haven't cleared yet. I modified the above snippet to work.