If Function and cin - c++

Im very new to c++ and trying to write a simple game to learn some of the basic mechanics and i'm having trouble with my code,
How do I define the function WantToPlay so that when a player enters "yes" it replies fantastic, and "no" replies boooo?
My current code gives the error that WantToPlay must be of bool type, but i'm not sure how to use a boolean function to rectify it?
Thanks!
using std::cout;
using std::cin;
using std::endl;
using std::string;
string leader;
string WantToPlay;
int main()
{
std::cout << "Dungeon Master: Welcome to my dungeon, traveller! What is your name?" << std::endl;
cin >> leader;
cout << "Dungeon Master: Well hello, " << leader << " I have a little quest for you if you're interested?" << endl;
cout << "(Please enter ""yes"" or ""no"")" << endl;
cin >> WantToPlay;
if (WantToPlay = "yes")
cout << "Fantastic!" << endl;
else if (WantToPlay = "no")
cout << "boooo" << endl;
return 0;
}

you need use the o̶p̶e̶r̶a̶t̶o̶r̶ c̶o̶m̶p̶a̶r̶a̶t̶o̶r̶ equality operator. "=="
What you are doing is assigning, not comparing.

(WantToPlay = "Yes") means assigning the string value "Yes" to the string variable WantToPlay
Since you are comparing the value of the variable with "Yes", you should use "==", because (WantToPlay == "Yes") means the string value "Yes" is the same as the value in string variable WantToPlay.

Did you know the difference between "=" and "==" ? Check your if statement, and correct it.
Tip: you can't use assignment in if condition.

Related

How to limit user input in C++ for strings & characters?

I'm trying to create a small restaurant program in which I'll be practicing everything I learned in C++ so far. However I jumped into a small issue. At the beginning of the program, I prompt the user whether they want to enter the program, or leave it by choosing Y or N. If the input is anything other than that the program will tell the user is invalid.
The issue is lets say the user input one invalid character a.
The invalid output will be displayed normally and everything seems perfect.
But if the user inputs two characters, or more, the invalid output case will be printed as many as the characters input by the user. Sample below:
Output image
#include <iostream>
int main()
{
char ContinueAnswer;
std::string Employee {"Lara"};
std::cout << "\n\t\t\t---------------------------------------"
<< "\n\t\t\t| |"
<< "\n\t\t\t| Welcome to OP |"
<< "\n\t\t\t|Home to the best fast food in Orlando|"
<< "\n\t\t\t| |"
<< "\n\t\t\t--------------------------------------|" << std::endl;
do
{
std::cout << "\n\t\t\t Would you like to enter? (Y/N)"
<< "\n\t\t\t "; std::cin >> ContinueAnswer;
if(ContinueAnswer == 'y' || ContinueAnswer == 'Y')
{
system("cls");
std::cout << "\n\t\t\t My name is " << Employee << "."
<< "\n\t\t\tI will assist you as we go through the menu." << std::endl;
}
else if(ContinueAnswer == 'n' || ContinueAnswer == 'N')
{
std::cout << "\t\t\t\tGoodbye and come again!" << std::endl;
return 0;
}
else
std::cout << "\n\t\t\t\t Invalid Response" << std::endl;
}
while(ContinueAnswer != 'y' && ContinueAnswer != 'Y')
Thank you for taking time to read and for anyone who answers :)
You could simply make the user input a string:
std::string ContinueAnswer;
and compare like this:
if(ContinueAnswer == "y" || ContinueAnswer == "Y")
which will handle multi-character inputs.
If you want to handle spaces in the input as well, change the:
std::cin >> ContinueAnswer;
to:
std::getline(std::cin, ContinueAnswer);
Before addressing your question I need to point out that you should always verify that the input was successful before doing anything with it. Processing variables which were not set due to the inout failing is a rather common source of errors. For example:
if (std::cin >> ContinueAnswer) {
// do something with successfully read data
}
else {
// deal with the input failing, e.g., bail out
}
I assume you consider everything on the same line to be invalid if nine of the expected characters was read. You could read a line into an std::string. However, that could be abused to provide an extremely long line of input which would eventually crash your program. Also, reading data into a std::string just to throw it away seems ill-advised. I’d recommend ignoring all characters up to and including a newline which could be done using (you need to include <limits> for this approach):
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), ‘\n’);
The first argument is a special value indicating that there may be an arbitrary amount of character before the newline. In practice you could probably use a value like 1000 and it would be fine but it can be gamed. Of course, in a real application a dedicated limit may be used to prevent an adversary to keep the program busy for long. I tend to assume my programs are under attack to make sure I deal with unusual cases.
A quick refactor produces this:
#include <iostream>
#include <cstring>
#include <stdio.h>
int main()
{
char ContinueAnswer[256];
std::string Employee {"Lara"};
std::cout << "\n\t\t\t---------------------------------------"
<< "\n\t\t\t| |"
<< "\n\t\t\t| Welcome to OP |"
<< "\n\t\t\t|Home to the best fast food in Orlando|"
<< "\n\t\t\t| |"
<< "\n\t\t\t--------------------------------------|" << std::endl;
do
{
std::cout << "\n\t\t\t Would you like to enter? (Y/N)"
<< "\n\t\t\t "; std::cin.getline(ContinueAnswer,sizeof(ContinueAnswer));
if(strcmp(ContinueAnswer, "Y") == 0 || strcmp(ContinueAnswer, "y") == 0)
{
system("cls");
std::cout << "\n\t\t\t My name is " << Employee << "."
<< "\n\t\t\tI will assist you as we go through the menu." << std::endl;
}
else if(strcmp(ContinueAnswer, "N") == 0 || strcmp(ContinueAnswer, "n") == 0)
{
std::cout << "\t\t\t\tGoodbye and come again!" << std::endl;
return 0;
}
else
std::cout << "\n\t\t\t\t Invalid Response" << std::endl;
}
while(true);
}
The cin.getline will get all characters until a delimiter. Then, you can check for equivalence using strcmp and reject anything other than what you want. Lastly, it seems like you are wanting this to be in an infinite loop, so don't worry about checking the input at the end and just loop back.

The if statements' condition

In exercise ten of chapter 3 in this book im trying to go over, I was asked to write a program that takes an operation followed by two operands and output the results.
Read the operation into a string called operations and use an if-statement to figure out which operation the user wants.Read the operands into variables of type double. Implement this for operations called +,-,*,/, you know (plus, minus, multiplication, division) the obvious.
This is what I wrote so far and it worked and all but my issues is the concept of the condition in the if-statements. From what I understand the if statement has parenthesis, that within are the conditions where the values are tested to see if they are true or false, Only after that the computer decided whether to run the code or not. So tell me why do I have to write the operation equal to the operator as the conditions, when I have to use the operator in the cout to get the results of the two input values anyway ? I don't understand this, isn't there a better way of writing this with less statements ?
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main()
{
string operation = "";
double operands1;
double operands2;
cout << "Give me either a minus, plus, division, or multiplication operations \n";
cin >> operation;
cout << " enter the value you would like to \n";
cin >> operands1;
cout << " enter the second value you would like to \n";
cin >> operands2;
if (operation == "+")// I was told to write it like this in the book {
cout << operands1 + operands2 << endl;
}
else if (operation == "*") {
cout << operands1*operands2 << endl;
}
else if (operation == "-") {
cout << operands1 - operands2 << endl;
}
else if (operation == "/") {
cout << operands1 / operands2 << endl;
}
else {
cout << " seriously dude im talking about numbers over here \n";
}
return 0;
}
For single character operations you can use a switch statement :
switch (c) {
case '+' : std::cout << op1 + op2 << std::endl; break;
case '*' : ...
...
default : std::cout << "my dud!" << std::endl;
}
If you care about number of statements, you could also use an ugly ternary operator:
std::cout << (c=="+" ? op1+op2 : c=="*" ? op1*op2 : "DUDEEE!") << std::endl;
If you're asking why you can't do something like this:
cout << operands1 operation operands2 << endl;
It's because that's not how the language is structured. You can't put a variable in a place where an operator would be and expect it to be substituted in. Suppose operation didn't contain an operand. What would happen then?
What you have now is the simplest way of handling this.
The assignment is somewhat confusing because the operator "+" is actually a string.
if (operation == "+")// I was told to write it like this in the book {
cout << operands1 + operands2 << endl;
}
The variable operation is a variable that holds letters and words. We call this type of variable a string variable. This is confusing to the least.
The if statement then asks whether the word contained in the variable operation is equal to the string "+". This is more confusing because we usually see a plus-sign as a symbol. In your program, the plus-sign "+" is a string.
So, the conditional in the parenthesis is asking if the operation string contains the string "+". If it does, then the code following that will be executed.
The + in the next line is now a real addition symbol, which will add the values in the two operands for printing.

"if" and "else if" commands are not working in c++

I am in the process of making a chat bot and i am just experimenting at this point. but my "if" commands are not working and when i enter "moodToday" it just skips right to the else command.
(capitalization of "moodToday" is not the error)
any and all help would be appreciated
#include <fstream>
#include <cmath>
using namespace std;
int main() {
char name[50], moodToday[50];
cout << "A few things you should know at this time..." << endl << "1. I can't process last names." << endl << "2. I can't process acronyms." << endl;
system("pause");
cout << endl << endl << "What is your name?" << endl;
cin >> name;
cout << "Hello " << name << "." << endl << "How are you today?" << endl;
cin >> moodToday;
//can't figure this out...
if ((moodToday == "sad") || (moodToday == "bad") || (moodToday == "horrible")) {
cout << "That's not good." << endl << "Why are you feeling " << moodToday << "today?" << endl;
}
else if (moodToday == "good") {
cout << "Great!" << endl;
}
else {
cout << "I'm sorry, I don't undrestand that feeling." << endl;
}
system("pause");
return 0;
}
To compare character arrays that contain strings you should use standard C functions like std::strcmp declared in header <cstring>. For example
#include <cstring>
//...
if ( std::strcmp( moodToday, "sad" ) == 0 ) std::cout << "They are equal << std::endl;
Otherwise in statements like this
if ((moodToday == "sad") ) /*...*/
there are compared two pointers: the pointer to the first character of the array moodToday and the pointer to the first character of the string literal "sad" because arrays used in expressions with rare exceptions are converted to pointers to their first characters.
Take into account that the usage of the operator >> with character arrays is unsafe
cin >> moodToday;
Use instead member function getline like this
cin.getline( moodToday, sizeof( moodToday ) );
Or instead of the character arrays you could use standard class std::string.
Consider a ppossibility to convert all letters of the entered string to the case of the string literal before comparing them. You can do this using standard C functions tolower and toupper declared in header <cctype>.
If you're doing C++, then you should be using std::string and not the old C-style buffers.
#include <string>
int main() {
std::string name, moodToday;
}
C++ strings are significantly better than C strings since they don't have buffer overflow problems and are easily compared with ==.
Also, as a tip, try to avoid using namespace std; since that can cause namespace conflicts. As annoying as it can be to type std:: all the time it does make it clear where that class or template originated from and who's responsible for it code-wise. That way your own classes and templates are obvious.
Use strcmp instead of == operators.
If you defined moodToday as a string object, then == would work.
Similar to problems in java with comparing object addresses what you are doing is comparing memory addresses. Thus you want to use strcmp(str1, "literal")==0 to see if they are equal.
#import <cstring>
if(strcmp(str1, "literal") == 0) dothis();

C++: STRING Function returns hexadecimal value instead of string

during my 2nd month learning C++ I got to this:
STRING type function to build up and return menu from two user-input dishes
(compliled and run in VisualStudio2013)
#include "../../std_lib_facilities.h"
string LeMenu(string meal, string dessert) //a F() concatenates 2 strings
{
return meal, dessert; //also tried meal+dessert
}
int main()
{
string course1, course2;
cout << "What is your chice today Sir?\n";
cin >> course1 >> course2; //request to input meals
LeMenu(course1,course2);
cout << "Is " << LeMenu << " ok?\n"; //here we output
keep_window_open();
}
But it always returns a HEXADECIMAL VALUE, and I do not know why:
(compliled and run in VisualStudio2013)
Is 012D15CD ok?
instead of Is JamEggs ok? (as an example)
From what I have learnt I do not see why, my text book does not even suggests this as a likely issue and I can not find any hint on the internet!.
More than a way to solve it it would be nice to understand if this is an expected mssbehavior or not. Thank you all!
You are printing out the function address of LeMenu. Try this instead:
cout << "Is " << LeMenu(course1, course2) << " ok?\n";
Note that you are what you are returning is probably not what you want:
return meal, dessert; //Only returns dessert
You probably want:
return meal + dessert;
cout << "Is " << LeMenu << " ok?\n";
Is printing the address of the function LeMenu() and not the returned string. To print the returned string you would need to call the function like:
cout << "Is " << LeMenu(course1,course2) << " ok?\n";
Also
string LeMenu(string meal, string dessert) //a F() concatenates 2 strings
{
return meal, dessert; //also tried meal+dessert
}
Is not going to return a concatenated string. It is using the comma operator and is only going to return the string dessert. You need to include the <string> header and then you can use the + operator like
return meal + dessert;
In
cout << "Is " << LeMenu << " ok?\n";
you print the address of the function.
you want
cout << "Is " << LeMenu(course1, course2) << " ok?\n";

How can I write a switch statement with strings in C++? [duplicate]

This question already has answers here:
Why can't the switch statement be applied to strings?
(22 answers)
Closed 3 years ago.
I'm working on a small project on Dev-C++. I'm trying to make a bot to ask you some questions, but I can't use the switch statetments with the strings. Every time I try to do so it shows error! I also tried to change the srings to normal int variables but when I the code runs all at once after answering the first question! Does anyone knows how to fix any of these situations?
Here is my code:
// #include "stdafx";
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
string comida;
string nome;
string idade;
string pais;
cout << "Ola, o meu nome e Aleksandar. Qual e o teu nome?" << endl; //Ask for nome
cin >> nome; //Recieve variable nome
cout << "Es de que pais, " << nome << "?" << endl; //Ask for pais
cin >> pais; //Receive pais
cout << pais << " e um pais bonito. " << "Eu sou de Portugal!" << endl;
cout << "Quantos anos tens " << nome << "?" << endl; //Ask for idade
cin >> idade; //Receive variable idade
switch (idade) {
case 21:
cout << "O meu irmao tambem tem 21 anos!" << endl;
break;
}
cout << "Eu tenho 28" << endl;
cout << "Qual e a tua comida preferida?" << endl; //Ask for comida
cin >> comida; //Receive variable comida
cout << "Tambem gosto muito de " << comida << ". Mas gosto mesmo e de Vatruchka!" << endl;
cout << "Xau " << nome << "!" << endl;
}
If the string contains a number, switch(std::stoi(idade)) will work. But that doesn't work if idade contains something else.
A switch will not compile when non-intergal (i.e. string, float, bool, vector, etc...) data-types are assigned to the switch's case: statements. Furthermore, its necessary that the values assigned to the case: statements are const.
In other words:
Switches must use "constant integral data-types" (i.e. 'enum', 'int', 'char', etc...), and cannot implament strings as conditional statements, however; that is not the same as saying that strings cannot be used in a conditional statement, they very much can be & often are — see the example below:
std::string s;
std::cin >> s;
if (s == "Yes")
{
std::cout << "You said yes!" << std::endl;
}
else if (s == "No")
{
std::cout << "You said no?" << std::endl;
}
else
{
std::cout << "You said something I don't understand" << std::endl;
}
So to finish this answer, you can see that you can achieve the same thing you could with a switch statement using if/else blocks. It may, or it may not, be ideal for your situation, but this is how C++, and switch statements work, so your stuck with it — like it, or not...
You can't use strings — switch only works for integral case types (i.e. integers and enums).
You could use something like this, instead:
if (idade == "21") { cout << "...\n"; }
else if (idade == "something else") { cout << "...\n"; }
You describe that the code runs all at once when you change to using integers. It's possible you're forgetting to include break in each case clause.
If you have a set of different strings that you are expecting then you can set up an enum and a map (I use the word map loosely here - I don't mean the actual map in C++, although I know it is possible to do something similar with it)
Use this to turn the input into an enum and then you can run a switch on the enum
E.g.
enum class ANSWER
{
ANSWER_1,
ANSWER_2
};
class AnswerMap \\set up this class like a singleton
{
std::vector<std::pair<std::string, ANSWER>> _answer_map = {
std::make_pair("Answer 1 string", ANSWER::ANSWER_1),
std::make_pair("Answer 2 string", ANSWER::ANSWER_2)
}
std::string String(ANSWER answer); \\have this function loop through this->_answer_map until finding the pair with the second item as the given enum and return the corresponding string
ANSWER Enum(std::string answer); \\have this function do the same as this->String but find the pair where the string matches and then return the corresponding enum
}