Could anyone help me with if statements and strings in C++? - c++

I am having a bit of trouble with if statements and strings/characters in c++. Here is my code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "-----------------------------" << endl;
cout << "|Welcome to Castle Clashers!|" << endl;
cout << "-----------------------------" << endl;
cout << "Would you like to start?" << endl;
string input;
cout << "A. Yes ";
cout << "B. No " << endl;
cin >> input;
if(input == "a" || "A"){
cout << "Yes" << endl;
}else{
if(input == 'b' || 'B'){
return 0;
}
}
return 0;
}
At my if statement it checks if the string input is equal to yes, and if it is not it should go to the else statement. This is where the trouble began, once I ran my program in the console when I type anything besides "a" or "A" it still says yes. I've tried doing it with chars/characters but I get the same output. Could anyone assist me?

It should be input == "a" || input == "A". You have to test each case individually. Right now your code is equivalent to (input == "a") || "A", which evaluates to true because "A" decays to a non-zero pointer.

"A" and 'B' will always be true in typical implementation.
You should also compare input against them.
Also compareing std::string with char doesn't seem supported, so you should also use string literals for b and B.
Try this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "-----------------------------" << endl;
cout << "|Welcome to Castle Clashers!|" << endl;
cout << "-----------------------------" << endl;
cout << "Would you like to start?" << endl;
string input;
cout << "A. Yes ";
cout << "B. No " << endl;
cin >> input;
if(input == "a" || input == "A"){
cout << "Yes" << endl;
}else{
if(input == "b" || input == "B"){
return 0;
}
}
return 0;
}

C didn't have "real" boolean values - instead, anything that equals 0 is considered false, and anything different from that is considered true. While C++ introduced a bool type, it still maintains the old C behavior for compatibility reasons.
As Cornstalk said, your (input == "a" || "A") is the same as ((input == "a") || ("A")), and "A" != 0, so it always evaluates to true - that's why it'll always enter into that if block. What you want is:
if (input == "a" || input == "A")
The same holds true to the next statement (comparing it to 'B'), but there's one extra problem in there: You're using single quotes ( ' ) instead of double quotes ( " ), which makes it a char instead of a string. To make both variables the same type, just use double quotes, and it'll end up like this:
if(input == "b" || input == "B")

Related

My code loops but its doesnt let me input something again after it loops how do I fix? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I have been at this for hours now, trying to figure out why my code isn't letting me re-enter my name after I say I want to register again.
Here's the code:
#include <iostream>
#include <string>
using namespace std;
int main() {
string full_name{};
string answer{"yes"};
while (answer1 == "yes" || answer1 == "Yes") {
string answer{}; cout << "Type your full name with a space inbetween: ";
getline(cin, full_name);
cout << full_name << " has been registered" << endl;
cout << "Do you want to clear your name from the list :";
cin >> answer;
if (answer == "yes" || answer == "Yes") {
full_name.clear();
}
else if (answer == "no" || answer == "No") {
cout << "Your name is still in the list" << endl;
}
cout << full_name << endl;
string answer1{};
cout << "\nDo you want to register again or someones else name?" << endl;
cin >> answer1; cout << endl;
if (answer1 == "no" || answer1 == "No") {
cout << "Thank you for registering" << endl; break;
}
}
}
When I say yes to cout << "\nDo you want to register again or someones else name?" << endl;, it loops back up, but skips cout << "Type your full name with a space inbetween: "; getline(cin, full_name);
Below are images of what I mean:
You need to use the member function ignore of the standard input stream something like
#include <limits>
//...
cout << "\nDo you want to register again or someones else name?" << endl;
cin >> answer1; cout << endl;
if (answer1 == "no" || answer1 == "No") {
cout << "Thank you for registering" << endl; break;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
that removes the new line character '\n' from the input stream that is stored in the stream buffer after this statement
cin >> answer1;
before calling std::getline in the next iteration of the loop. Otherwise the next call of std::getline will read an empty string.

Can't figure out how to give user all the options for starting, stopping, and restarting program?

Ok so I am trying to build this random number teller which basically tells the users whether the number they input is less than, greater than, or equal to 50 and also give them the options to start, stop, and restart the "random number teller" Here is the code:
#include <iostream>
using namespace std;
main() {
cin >> boolalpha;
int invalid_answer {0};
const int const_num {50};
int random_num {};
char answer {};
int keep_going {};
while (keep_going == 0) {
while (invalid_answer == 0) {
//=======================================================================================================================================
cout << "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " << endl;
cin >> random_num;
if (random_num > const_num) {
cout << random_num << " is greater than " << const_num;
}
else if (random_num == const_num) {
cout << random_num << " is the same as " << const_num << endl;
}
else {
cout << random_num << " is less than " << const_num << endl;
}
cout << "Want to try again? Type \"Y\" or \"N\"";
cin >> answer;
//=======================================================================================================================================
if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}
//=======================================================================================================================================
while(answer == 'Y') {
cout << "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " << endl;
cin >> random_num;
if (random_num > const_num) {
cout << random_num << " is greater than " << const_num;
}
else if (random_num == const_num) {
cout << random_num << " is the same as " << const_num << endl;
}
else {
cout << random_num << " is less than " << const_num << endl;
}
cout << "\nWant to try again? Type \"Y\" or \"N\"";
cin >> answer;
}
//=======================================================================================================================================
if (answer != 'Y' || answer != 'N') {
invalid_answer = 1;
}
//=======================================================================================================================================
while (invalid_answer == 1) {
cout << "I'm sorry what? Please note that answers are case sensitive. Answer again: ";
cin >> answer;
if (answer == 'Y') {
invalid_answer = 0;
}
else if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}
}
}
}
}
Whenever I say "N" for No I don't want to redo the random number checker, it doesn't change keep_going to 1 it just moves on to one of the other if or while statements below it. So when you input "N" it just outputs either "Enter a random number and we will tell you if it is greater than or less than " << const_num << ": " or "I'm sorry what? Please note that answers are case sensitive. Answer again: "
The problem is with this bit of code:
if (answer != 'Y' || answer != 'N') {
invalid_answer = 1;
}
When answer is 'N', answer != 'Y' is true and invalid_answer is set to 1 (because of short-circuit evaluation the rhs of the logical OR is not even evaluated - see quote below).
So the execution will enter the while
while (invalid_answer == 1)
and will print the statements.
You can correct this by:
if (answer == 'Y' || answer == 'N') { //if input is either 'Y' or 'N'
invalid_answer = 0;
}
else { //for all other inputs
invalid_answer = 1;
}
Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands
Also note that main should have the type int.
I figured it out right after I posted the question haha, basically the answer above was correct so I had to split that if statement into 2 others, in which I added an else statement to each also that said invalid_answer = 0; to make sure. But then after the user's second time using the program, if they wanted to quit it wouldn't let them and would just restart it again. I solved that by adding
if (answer == 'N') {
cout << "Ok then, sorry to see you miss out" << endl;
keep_going = 1;
}`
to the bottom of the while(answer == 'Y') loop.

How to end my while loop? [duplicate]

This question already has answers here:
Immediate exit of 'while' loop in C++ [closed]
(10 answers)
Closed 6 years ago.
Hey can anyone lend me a hand? How can I make my loop end after the first calculation? After i complete one calculation such as addition, I would like to end it. Sorry for the noobie questions. I'm just learning loops now in my class. Greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int numOne;
int numTwo;
int result;
string operation;
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
while (operation == "e" || operation == "E")
{
cout << "Operation type invalid." << endl;
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
}
while (operation == "+" || operation == "-" || operation == "*" || operation == "/")
{
cout << "Please enter integer one: ";
cin >> numOne;
cout << "Please enter integer two: ";
cin >> numTwo;
if (operation == "+")
{
result = numOne + numTwo;
cout << "The numbers you entered were " << numOne << "," << numTwo << endl;
cout << "The operation you chose was " << operation << "." << endl;
cout << "The operations result is " << result << "." << endl;
cout << "Your equation was: " << numOne << " " << operation << " " << numTwo << " = " << result << ".";
}
else if (operation == "-")
{
result = numOne - numTwo;
cout << "The numbers you entered were " << numOne << "," << numTwo << endl;
cout << "The operation you chose was " << operation << "." << endl;
cout << "The operations result is " << result << "." << endl;
cout << "Your equation was: " << numOne << " " << operation << " " << numTwo << " = " << result << ".";
}
else if (operation == "*")
{
result = numOne * numTwo;
cout << "The numbers you entered were " << numOne << "," << numTwo << endl;
cout << "The operation you chose was " << operation << "." << endl;
cout << "The operations result is " << result << endl;
cout << "Your equation was: " << numOne << " " << operation << " " << numTwo << " = " << result << ".";
}
else if (operation == "/")
{
if (numTwo == 0)
{
cout << "You cannot divide by zero!" << endl;
}
else
{
result = numOne / numTwo;
cout << "The numbers you entered were " << numOne << "," << numTwo << endl;
cout << "The operation you chose was " << operation << "." << endl;
cout << "The operations result is " << result << endl;
cout << "Your equation was: " << numOne << " " << operation << " " << numTwo << " = " << result << ".";
}
}
}
return 0;
}
I'm not allowed to use break. Is there another way?
You can end a while loop using...
break;
ie
if(!(operation == "e" || operation == "E")) {
break;
}
Normally to end a while loop the (EXPRESSION) in the following ie
while((EXPRESSION) == true) { execute_code_here();}
needs to evaluate to false. The expression can be made up of many logical pieces ie
while (a == b && c != d && f++ < 1000) {do_something_here();}
The break keyword is used to terminate a while loop early but this can also be achieved by adding something to the expression that allows you to terminate the while loop ie make the expression evaluate to false, this is normally done using a flag or a counter.
To achieve the same effect as break without using it you can use this technique with continue. You then use the flag or counter along with continue to achieve the same thing as break ie, this is a counter example
while(a == b && flag++ < 1000) {
if(this_returns_true()) {
flag = 10000;
continue;
}
/*The code here may not be executed*/
}
Using a boolean flag it would be...
while(a == b && flag == true) {
if(this_returns_true()) {
flag = false;
continue;
}
/*The code here may not be executed*/
}
Just change the while to if. There's no need for a loop if you only want to execute something once.
You can use break; with an if statement inside the while loop. So that if a condition is true you will break out from the while loop.
Example
if (operation != "e")
break;
If you're not allowed to use break, I suggest you don't use a loop. And just calculate it once.
I am not very experienced with C++ but I think you mean the break; statement
https://msdn.microsoft.com/library/37zc9d2w.aspx
Use
break;
This will end the loop each time. You can wrap an if statement around it to apply conditions for exiting.
If you have to use the while loop just add break; and that will break out of the loop. If you don't have to I would change that to an if statement. Example: if(varName == '+'){
Num1 + num2;}
Sorry for format, on mobile
The code block:
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
while (operation == "e" || operation == "E")
{
cout << "Operation type invalid." << endl;
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
}
Doesn't do what you're promising the user:
Please enter what operation you'd like to perform or e/E to end program:
If "e" or "E" is entered, the loop won't stop and ask for input again.
You probably want to have something like this:
do {
cin >> operation;
while (operation == "+" || operation == "-" || operation == "*" || operation == "/") {
// ...
}
} while(operation != "e" && operation != "E");
As for your silly restrictions not to use do {} while(); (kick your professor in the ass, do twice at least):
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
while(operation != "e" && operation != "E") {
if (operation == "+" || operation == "-" || operation == "*" || operation == "/") {
// ...
}
else {
cout << "Operation type invalid." << endl;
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
}
}
I guess that what you are actually trying to achieve is this.
The first loop should be refactored (ie: loop until operation is nether 'e' nor 'E'), the second loop should be an if-else-statement (checking whether the operation is valid).
int main()
{
int numOne;
int numTwo;
int result;
string operation;
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
while (operation != "e" && operation != "E") {
if (operation == "+" || operation == "-" || operation == "*" || operation == "/") {
// your valid operation code...
} else {
cout << "Operation type invalid." << endl;
}
cout << "Please enter what operation you'd like to perform or e/E to end program: ";
cin >> operation;
}
return 0;
}

How to check user input?

SO I want to be able to invalidate all user input except a certain word, like 'K' or 'C'. I'm not sure at all how to do this. So if they mispell it to "celcius" or "husdhfjae", my program would say "Input invalid, please enter K or C."
Please nothing too complicated, because I just started. Thank you :)
// CS 575,HW #1B, Ravela Smyth
// This program converts from Fahrenheit to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
double Fahrenheit, celsius, kelvin;
cout << "Hi! What is the weather today in Fahrenheit?? " << endl;
cin >> Fahrenheit;
cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << endl;
cin >> input;
if (input == "C")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "c")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "K")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
else if (input == "k")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
return 0;
}
Usually user inputs are checked using while or do...while loops.
The idea is simple, you always get back to the same error message and read again the input until it is correct.
The advantage of placing the valid options in the single string is to allow easy addition or removal of the options without dealing with long if conditions.
I believe something simple like this will do the job:
std::string valid_options("kKcC");
std::string input;
bool illegal_input;
std::cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << std::endl;
std::cin >> input;
// check that only one letter was provided and it belongs to the valid options
while (input.size() != 1 || valid_options.find(input) == std::string::npos)
{
std::cout << "Input invalid, please enter K or C.\n";
std::cin >> input;
}
First, you can do something like if(input == "C" || input == "c")
Or you can convert the input to lower/upper case
Second, you can add an else statement that says something like "please enter a valid command". Play around with it, you can even use loops to wait for correct input!
My approach is to test the input against a container of all valid inputs.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
bool valid(std::string s,std::vector<std::string> y)
{
std::sort(y.begin(), y.end());
return std::binary_search(y.begin(), y.end(), s);
}
int main()
{
std::string s;
do
{
std::cout << "Enter K or C: ";
std::cin >> s;
} while (!valid(s, { "K","C","k","c" }));
std::cout << "good!" << std::endl;
return 0;
}
You need a while loop. This is probably the simplest way to do it.
#include <iostream>
#include <string>
int main()
{
std::string word;
std::cin >> word;
//Keep asking for a word until this condition is false, i.e.
//word will be equal to one of these letters
while(word != "C" && word != "c" && word != "K" && word != "k")
{
std::cout << "Invalid temperature type: " << word << " Use 'K' or 'C'" << std::endl;
std::cin >> word;
}
if (word == "C" || word == "c")
{
std::cout << "Celsius" << std::endl;
}
else if (word == "K" || word == "k")
{
std::cout << "Kelvin" << std::endl;
}
}
I had the same problem while getting the correct user input for that i wrote a simple solution i hope it will be helpfull for everyone getting started with c++.
//get user input
char input;
cin >> input;
//convert the input to lowercase
char Temp = tolower(input);
//check the input (not valid input will clear the user input)
while(!(cin >> input) || ((Temp != 'c') &&( Temp != 'k')){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please, try again: ";
}
//evalute input cases
switch (Temp)
{
case 'c':
/* celcius */
break;
case 'k':
/* Kelvin */
break;
}

Problems using cin in C++

So, I've just begun learning c++, and i've been watching some tutorials, etc. I wrote a small program that should act like a magic eight ball, however I'm having some troubles with the cin command. I've written cin >> x; where x is a string, and when the user types their question, the program is supposed to print a random response. Sounds simple enough, but if the user types more than 1 word in the question, more than 1 response is printed. So, if i type "Will I live to be 100?" I get 6 answers instead of 1. Here's my code: (I'm sure it's probably messy and not very well organized or coded in the most efficient way, like I said, I'm a beginner.)
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
string z = "Yes";
string b = "Signs point to yes";
string c = "It is certain";
string d = "It is decidedly so";
string e = "Without a doubt";
string f = "Yes, definitely";
string g = "You may rely on it";
string h = "As I see it yes";
string i = "Most likely";
string j = "Outlook good";
string k = "Reply hazy try again";
string l = "Ask again later";
string m = "Better not tell you now";
string n = "Cannot predict now";
string o = "Concentrate and ask again";
string p = "Don't count on it";
string q = "My reply is no";
string r = "My sources say no";
string s = "Outlook not so good";
string t = "Very doubtful";
string u;
int main()
{
srand(time(0));
cout << "Ask A Question" << endl << endl << "Type 'Exit' to end the program" << endl << endl;
int a = 1+(rand()% 20);
cin >> u;
if (u == "Exit"){
return 0;
}
if (u == "exit"){
return 0;
}
if (a == 1){
cout << z << endl << endl;
main();
}
if (a == 2){
cout << b << endl << endl;
main();
}
if (a == 3){
cout << c << endl << endl;
main();
}
if (a == 4){
cout << d << endl << endl;
main();
}
if (a == 5){
cout << e << endl << endl;
main();
}
if (a == 6){
cout << f << endl << endl;
main();
}
if (a == 7){
cout << g << endl << endl;
main();
}
if (a == 8){
cout << h << endl << endl;
main();
}
if (a == 9){
cout << i << endl << endl;
main();
}
if (a == 10){
cout << j << endl << endl;
main();
}
if (a == 11){
cout << k << endl << endl;
main();
}
if (a == 12){
cout << l << endl << endl;
main();
}
if (a == 13){
cout << m << endl << endl;
main();
}
if (a == 14){
cout << n << endl << endl;
main();
}
if (a == 15){
cout << o << endl << endl;
main();
}
if (a == 16){
cout << p << endl << endl;
main();
}
if (a == 17){
cout << q << endl << endl;
main();
}
if (a == 18){
cout << r << endl << endl;
main();
}
if (a == 19){
cout << s << endl << endl;
main();
}
if (a == 20){
cout << t << endl << endl;
main();
}
return 0;
}
The problem is that you are calling main() over and over (recursively) in order to let the user ask another question. However, you don't take into account that std::cin stops extracting a string when it encounters a space, so you will end up making as many repetitions as there are whitespace-separated words in the user input.
Apart from this problem, the code is horrible. Sorry, it just is:
I. You declare 20 (or so) variables and a whole bunch of ifs instead of an std::vector<std::string>. This will quickly become unmaintainable if you have more elements or if you don't know the number of items.
II. You are calling main() recursively, which is legal but illegal and evil and shows a terribly bad programming style. Just don't do it. Use a loop (iterations) instead.
III. You are abusing namespace std; which is also discouraged.
IV. You are also using global variables with no good reason.
All in all, you should rewrite your program so that it reads something like this:
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
std::vector<std::string> v;
v.push_back("Yes");
v.push_back("Signs point to yes");
v.push_back("It is certain");
v.push_back("It is decidedly so");
v.push_back("Without a doubt");
v.push_back("Yes, definitely");
v.push_back("You may rely on it");
v.push_back("As I see it yes");
// etc.
char q[0x100] = { 0 };
while (true) {
std::srand(std::time(nullptr));
int idx = rand() % v.size(); // this isn't perfect either, by the way
std::cout << "Ask a question:" << std::endl;
std::cin.getline(q, sizeof(q));
if (std::string(q) == "exit")
break;
std::cout << v[idx] << std::endl;
}
return 0;
}
And boom, it's just 37 lines instead of 128, and it's much readable.
cin reads a string just till the space is reached so basicly "Will I live to be 100?" contains 6 strings.
In order to avoid your problem use getline
Also you should better change your 20 string variables to a single array or vector of strings. In this case your main() will also look better as you will end up having just ONE if statemnt which will access an element of your array\vector depending on the random value.
Also you should move your global variables to main() and insert your code in a while loop which will have the following condition while (cin >> u && u != "exit") (leave only your variables declarations and srand(time(0)); outside the loop)
This answer shows how your program should actually look like.
Use getline to read a complete line
The problem here, among arguably others, is that cin stops whenever it encounters a space, and your stdin has already buffered that entire question (line), so the next time you call cin actually it reads what you had in the stdin buffer.
You should consider using getline function, that reads until a line break/carriage return.
getline(cin,u);
You should also consider learning loops, to not call main() again, and arrays for better structuring your code.