Validating user input isn't displaying my cout invalid message. Why? - c++

I'm trying to write a Euro/USD converter. I'm brand new to programming and c++. I don't know what I did wrong. I don't have any errors, but whenever I don't type the string im checking for the
std::cout << "Invalid. Please type Euros or USD. No stupid weird CAPS." << std::endl;
doesn't display.
Here's the full code:
#include <iostream>
#include <limits>
int main() {
while (true) {
// Used later when validating user input.
full_restart:
// Initial convert selector:
std::cout << "What currency do you want to convert? Euros or USD?\nPlease type Euros or USD:" << std::endl;
std::string currency_type{"hello"};
restart:
std::cin >> currency_type;
// Validating user input:
while (true) {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid. Please type Euros or USD. No stupid weird CAPS." << std::endl;
goto restart;
} else if (!std::cin.fail()) {
break;
}
}
if (currency_type == "euros" || currency_type == "Euros" || currency_type == "EUROS") {
std::cout << "How many Euros do you want to convert to USD?\nEnter the number: " << std::endl;
double euro_amount_to_convert{0};
euro_restart:
std::cin >> euro_amount_to_convert;
while (true) {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid. Please enter either Integer or Decimal." << std::endl;
goto euro_restart;
} else if (!std::cin.fail()) {
break;
}
}
double euros_converted_to_usd = euro_amount_to_convert * 1.11237;
std::cout << euro_amount_to_convert << " euros equals " << euros_converted_to_usd << " USD." << std::endl;
std::cout << "Would you like to convert another currency?\nPlease type 'Y' or 'N'" << std::endl;
char go_again{'a'};
std::cin >> go_again;
euro_convert_again:
std::cout << "Would you still like to convert another currency?\nPlease type 'Y' or 'N'" << std::endl;
std::cin >> go_again;
while (true) {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input." << std::endl;
goto euro_convert_again;
} else if (!std::cin.fail()) {
break;
}
}
if (go_again == 'Y' || go_again == 'y') {
goto full_restart;
} else if (go_again == 'N' || go_again == 'n') {
break;
}
}
if (currency_type == "usd" || currency_type == "Usd" || currency_type == "USD") {
std::cout << "How many USD do you want to convert to Euros?\nEnter the number: " << std::endl;
double usd_amount_to_convert{0};
usd_restart:
std::cin >> usd_amount_to_convert;
while (true) {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid. Please enter either Integer or Decimal." << std::endl;
goto usd_restart;
} else if (!std::cin.fail()) {
break;
}
}
double usd_converted_to_euros = usd_amount_to_convert * 1.11237;
std::cout << usd_amount_to_convert << " USD equals " << usd_converted_to_euros << " Euros." << std::endl;
std::cout << "Would you like to convert another currency?\nPlease type 'Y' or 'N'" << std::endl;
char go_again{'a'};
std::cin >> go_again;
usd_convert_again:
std::cout << "Do you still want to convert another currency?\nPlease type 'Y' or 'N'" << std::endl;
std::cin >> go_again;
while (true) {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input." << std::endl;
goto usd_convert_again;
} else if (!std::cin.fail()) {
break;
}
}
if (go_again == 'Y' || go_again == 'y') {
goto full_restart;
} else if (go_again == 'N' || go_again == 'n') {
break;
}
}
}
std::cout << std::endl;
return 0;
}
Also, I'm aware there are probably many better ways to do this, this is just practice for me. I'm pretty sure it's the loops since this is the first time I've used them.

cin.fail() doesn't become true just because the input isn't what you want it to be. The compiler can't read your mind. If you want to restrict the input to certain strings you have to check for that explicitly.
E.g.
std::string currency_type{"hello"};
std::cin >> currency_type;
if (currency_type == "euros" || currency_type == "Euros" || currency_type == "EUROS") {
...
} else if (currency_type == "usd" || currency_type == "Usd" || currency_type == "USD") {
...
} else {
std::cout << "Invalid. Please type Euros or USD. No stupid weird CAPS." << std::endl;
}
cin.fail() does become true if a read fails completely, e.g. if you try to read an integer, but the user types in letters. But that's a different situation to this.

You only show that message when std::cin.fail(), but there's no reason for this to be true.
You read into a string, which is always going to work. The computer does not know that you only wanted the string "Euros" or the string "USD" to be valid.
You'll want to replace your check with a value comparison.

currency_type is a std::string. This means that cin will never enter a failed state as whatever you enter can be placed in a string. What you need to do is inspect what is in the string, and if it is not what you want then give an error message. That would mean you need a check like:
if (!(currency_type == "euros" || currency_type == "Euros" || currency_type == "EUROS"
currency_type == "usd" || currency_type == "Usd" || currency_type == "USD"))
{
std::cout << "Invalid. Please type Euros or USD. No stupid weird CAPS." << std::endl;
goto restart;
}

Related

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 handle invalid inputs while displaying Game menus?

#include <iostream>
#include <string>
using namespace std;
int main() { //Program starts
cout << "-------------------------------" << endl;
cout << "Welcome to Ninjas vs. Samurais!" << endl; //The intro
cout << "-------------------------------" << endl;
string newAdventure;
string chosenKind;
cout << "Hello, new solder! Are you ready for your adventure to begin, yes or no?\n"; //Asks you if you are ready
cin >> newAdventure;//Takes in if you are ready or not
if (newAdventure == "yes" || newAdventure == "Yes" || newAdventure == "Yes!") { //Asks if they are ready
cout << "Great!\n" << endl;
}
else if (newAdventure == "no" || newAdventure == "No" || newAdventure == "No!") { //Asks if they are ready
cout << "Too bad!\n" << endl;
}
else {
cout << "Please type a yes or no answer!\n";
}
system("PAUSE");
return 0;
}
If the user didn't input a valid answer, how could I make them restart the question? Would I have to use a loop? If so, how would I do that?
Yes you would have to use a loop. Something like:
while(cin >> newAdventure)//Takes in if you are ready or not
{
if (newAdventure == "yes" || newAdventure == "Yes" || newAdventure == "Yes!") { //Asks if they are ready
cout << "Great!\n" << endl;
break;
}
else if (newAdventure == "no" || newAdventure == "No" || newAdventure == "No!") { //Asks if they are ready
cout << "Too bad!\n" << endl;
break;
}
else {
cout << "Please type a yes or no answer!\n";
}
}
The break keyword will exit the loop once your answer is valid, otherwise, it keeps going.
You can add a condition like this:
while(true)
{
cout << "Hello, new solder! Are you ready for your adventure to begin, yes or no?\n"; //Asks you if you are ready
cin >> newAdventure;//Takes in if you are ready or not
if (newAdventure == "yes" || newAdventure == "Yes" || newAdventure == "Yes!") { //Asks if they are ready
cout << "Great!\n" << endl;
break;
}
else if (newAdventure == "no" || newAdventure == "No" || newAdventure == "No!") { //Asks if they are ready
cout << "Too bad!\n" << endl;
break;
}
else {
cout << "Please type a yes or no answer!\n";
}
}

Converting Integers to Strings and If.. Else Boolean Functions C++

I am working on this assignment that requires me to create a game of rock, paper scissors for my programming class. I have ran into a couple issues that I am not fully educated about as I am still learning the basics of this language. My professor wants me to take in the users choice and the computers choice and then change it from an int to a string and print it out as "You chose: Rock" instead of "You chose: 1" which is what it is doing now. This part would be in the getComputerChoice() and getPlayerChoice() functions. Another issue I am having trouble with is my professor wants us to check if it was a tie or if the player won and I am trying to put these functions in an If else statement but I am not exactly sure what the proper way to declare the function in the else statement is. (This is commented out in the else part of the if statement in main all the way at the bottom)
My code is as follows:
#include <iostream>
#include <iomanip>
#include <string>
#include <ctime>
using namespace std;
int getComputerChoice();
int getPlayerChoice();
bool isTie(int, int);
bool isPlayerWinner(int, int);
int getComputerChoice()
{
int comp;
string cpChoice;
comp = rand() % 3 + 1;
if (comp == 1)
{
cpChoice = "Rock";
}
else if (comp == 2)
{
cpChoice = "Paper";
}
else if (comp == 3)
{
cpChoice = "Scissors";
}
return comp;
}
int getPlayerChoice()
{
int userChoice;
string strChoice;
cout << "Rock, Paper, or Scissors?\n";
cout << "1) Rock\n";
cout << "2) Paper\n";
cout << "3) Scissors\n";
cout << "Please enter your choice : \n";
cin >> userChoice;
cout << '\n';
while(userChoice < 1 || userChoice > 3)
{
cout << "Invalid Selection\n";
cout << "Re-enter a number between 1 and 3\n";
cin >> userChoice;
}
if (userChoice == 1)
{
strChoice = "Rock";
}
else if (userChoice == 2)
{
strChoice = "Paper";
}
else if (userChoice == 3)
{
strChoice = "Scissors";
}
return userChoice;
}
bool isTie(string userChoice, string comp)
{
if (userChoice != comp)
return false;
else
return true;
}
bool isPlayerWinner(int userChoice, int comp)
{
if ((comp == 1 && userChoice == 2) || (comp == 3 && userChoice == 1) || (comp == 2 && userChoice == 3))
return true;
else
return false;
}
int main()
{
char selection;
int computerChoice;
int userChoice1;
string Rock;
string Paper;
string Scissors;
srand ((unsigned int)time(NULL));
do
{
cout << '\n';
cout << "ROCK PAPER SCISSORS MENU\n";
cout << "-------------------------\n";
cout << "p) Play Game\n";
cout << "q) Quit\n";
cout << "Please enter your choice : \n";
cin >> selection;
cout << '\n';
cout << '\n';
// cin >> selection;
if (selection == 'p' || selection == 'P')
{
computerChoice = getComputerChoice();
//string computerChoice = to_string(comp);
userChoice1 = getPlayerChoice();
//string userChoice1 = to_string(userChoice);
cout << "You chose: " << userChoice1 << '\n';
cout << "The computer chose: " << computerChoice << '\n';
if (isTie(computerChoice, userChoice1)== true)
{
cout << "You choose: " << userChoice1;
cout << "The computer chose: " << computerChoice;
cout << "It's a TIE!";
}
else //(isPlayerWinner(computerChoice, userChoice1));
{
cout << "You choose: " << userChoice1;
cout << "The computer chose: " << computerChoice;
cout << "You WIN!";
}
}
//else if (selection != 'p' || selection != 'q')
//{
// cout << "Invalid Selection. Try Again.\n";
// cout << '\n';
// cin >> selection;
//}
else if (selection == 'q' || selection == 'Q')
{
cout << "You have chosen to quit the program. Thank you for using the program!\n";
}
else if (selection != 'p' || selection != 'q')
{
cout << "Invalid Selection. Try Again.\n";
cout << '\n';
}
}while (selection != 'q');
}
ANOTHER NOTE: my professor doesn't want any void functions and doesn't want any global variables.
She told me that my isTie function was fine but didn't mention anything about the isPlayerWinner function. I believe it is fine and has no issues, I am just not sure how to declare it in the main if else statement. Any help would be appreciated and if you guys have any questions or need more info please let me know. Thanks in advance.
You pretty much have everything right.
Your getPlayerChoice() and getComputerChoice() functions right now are both returning an int that stand for the players choice. You calculate the name for that choice in those functions, but dont do anything with the actual string representing the choice. You either need to return the choice string, or make a function that takes in an int and returns name associated with that choice:
string getChoiceName(int choice)
{
string strChoice;
if (choice== 1)
{
strChoice = "Rock";
}
else if (choice== 2)
{
strChoice = "Paper";
}
else if (choice== 3)
{
strChoice = "Scissors";
}
return strChoice;
}
I prefer the method, as it make it easier to calculate the result of the match if you have the ints. There are a lot of other routes you could take, like making an enum representing choices - even the function I gave you here isn't great, but it should get you to a working state.

Input errors in c++ program

when press "1" to start the game a error message comes up first instead of playing the game and then I have to enter "1" 3 times before the game starts and also the quit game option only works when you select "2" first if its not selected first it just comes up as a error message I cant see why it does this can anyone help me please ?
#include "Questions.h"
#include <iostream>
using namespace std;
const int MAXITEMS = 10;
int main ()
{
string question[MAXITEMS] = {"How man cards in a suit",
"How_many_suits_are_there_in_a_standard_pack_of_card",
"How_many_kings_are_in_a_standard_pack_of_cards"};
string answers[MAXITEMS] = {"4", "5", "6"};
int userInput = 0;
int tries = 0;
bool isGameOver = false;
cout << "select 1 to start game" << endl; //gives option to start and quit game
cout << "select 2 to quit game" << endl;
cin >> userInput;
if (userInput == 2)
{
isGameOver = true;
return 0;
};
// when game starts gives option to select question and shows all questions
do
{
if (userInput != 1||2)
{
cout << " Your input is not valid! please try again:" << endl;
// try switch cases for the different outcomes
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
cin >> userInput;
while (!(cin >> userInput))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n'); // discard the row
cout << "Your input is not valid! please try again: ";
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
}
cout << userInput << endl;
}
// reprisent all characters as number to stop while roblem
if(userInput == 1)
{
do
{
cout << "select question" << endl;
for(int i = 0; i != MAXITEMS; i++)
{
cout << i << " " << question[i] << endl;
}
int selectQestion;
cin >> selectQestion;
if(selectQestion == 0||1||2 && tries != 2)
{
cout << "Enter your answer" << endl;
string userAnswer;
cin >> userAnswer;
while (!(cin >> userAnswer))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n');
// discard the row
cout << "Your input is not valid!
please try again: ";
}
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else{
cout << "incorrect try again" << endl;
tries++;
cin >> userAnswer;
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else
cout << "Incorrect" << endl;
}
}
if (selectQestion == 0 ||1 ||2 && tries == 2)
{
cout << "you can no longer answer this question" << endl;
cout << "try another question" << endl;
}
}
while(userInput == 1);
}
}
while(isGameOver == false);
}
// add stuct or class to handle questions,
if (userInput != 1||2) doesn't do what you think. With the proper paretheses inserted, it is
if ((userInput != 1) || 2)
and 2 is nonzero, hence the condition is always true.
You want
if (userInput != 1 && userInput != 2)
The problem lies here:
if (UserInput!=1||2)
In this line, there are two conditions:
UserInput!=1 , 2
Here , whether user input is 1/2, the second condition 2 is always evaluated as true, which runs the if block
So change it to
if (UserInput!=1 && UserInput!=2)

C++ Calculator Skipping Else Statement

I was making a simple calculator in C++. However the program does not completely function the way it should. When run, the trig if statement executes fine, however, the basic arithmetic else statement doesn't work. I have determined that the code is not executing the else statement and was wondering how to fix it. The code inside the else statement works fine, as I have commented out the if statement. Help?
Here is my code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
int main()
{
double input = 0;
double firstnumber = 0;
double secondnumber = 0;
std::string function;
std::string operation;
std::cout << "Enter your calculation: ";
std::cin >> function;
if(function == "sin" || "cos" || "tan")
{
if(function == "sin")
{
std::cin >> input;
std::cout << "The sine is " << sin(input) << std::endl;
system("PAUSE");
}
else if(function == "cos")
{
std::cin >> input;
std::cout << "The cosine is " << cos(input) << std::endl;
system("PAUSE");
}
else if(function == "tan")
{
std::cin >> input;
std::cout << "The tangent is " << tan(input) << std::endl;
system("PAUSE");
}
}
else
{
firstnumber = ::atof(function.c_str());
std::cin >> operation;
std::cin >> secondnumber;
double valueadd = firstnumber + secondnumber;
double valuesubtract = firstnumber - secondnumber;
double valuemultiply = firstnumber * secondnumber;
double valuedivide = firstnumber / secondnumber;
if(operation == "+")
{
std::cout << " = " << valueadd << std::endl;
system("PAUSE");
}
else if(operation == "-")
{
std::cout << " = " << valuesubtract << std::endl;
system("PAUSE");
}
else if(function == "*")
{
std::cout << " = " << valuemultiply << std::endl;
system("PAUSE");
}
else if(function == "/")
{
std::cout << " = " << valuedivide << std::endl;
system("PAUSE");
}
else
{
std::cout << "Error" << std::endl;
return 0;
}
}
return 0;
}
This line is wrong.
if(function == "sin" || "cos" || "tan")
It should be
if((function == "sin") || (function == "cos") || (function == "tan"))
Note that the check is actually meaningless because you already check for them each individually. You could tidy this up by doing this in a if, else if, else chain.
You must write out each condition separately. The following line of code compiles but it doesn't do what you think:
if (function == "sin" || "cos" || "tan")
Change it to the following:
if (function == "sin" || function == "cos" || function == "tan")
Since you want to do something different for each trig function, you should just have a single if...else if...else if...else if...else chain. There is no need to nest the if statements as you have. In fact, it is probably less efficient because you check each condition twice.
Change:
if(function == "sin" || "cos" || "tan")
into:
if ((function == "sin") || (function == "cos") || (function == "tan"))
What you have first calculates the expression "sin" || "cos" || "tan" and then tries to compare the string with that.
But, in fact, it's not really necessary to have this two-step process. You can simply do something like this:
if (function == "sin") {
std::cin >> input;
std::cout << "The sine is " << sin (input) << std::endl;
system ("PAUSE");
} else if (function == "cos") {
std::cin >> input;
std::cout << "The cosine is " << cos (input) << std::endl;
system ("PAUSE");
} else if (function == "tan") {
std::cin >> input;
std::cout << "The tangent is " << tan (input) << std::endl;
system ("PAUSE");
} else {
// It's neither sin, cos nor tan if you get here.
firstnumber = ::atof (function.c_str ());
// and the rest of your stuff in here.
}