Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to use a menu in C++ that has options both in letters and numbers. For example, the output might be:
========================
(1) Do something
(2) Do something
(a) Do something
(b) Do something
========================
Is there a method for testing user input to determine if it is a char or int and handle it accordingly?
If I use:
int choice;
cin >> choice;
And the user inputs a char, of course cin will return an error. I'm looking for a simple method to test user input for a digit or a character and have the program react differently based on that determination.
[UPDATE]
I've found the answer I was looking for. Here's how I did it:
string choice;
cout << "Your choice: ";
cin >> choice;
if( isdigit(choice[0]) )
{
theInt = stoi(wChoice);
// do something with int
}
else if( choice[0] = 'a' )
// do menu option a
You'd better use the method isdigit in the ctype.h to check if character is a decimal digit character, and the method isalpha to check if character is alphabetic.
"For example, there could be options: 1, 2, 3, n, s."
The simplest solution I see is to have a menu selection code like
char choice;
std::cin >> choice;
switch(choice) {
case `1`:
// Do menu option one
break;
case `2`:
// Do menu option two
break;
case `3`:
// Do menu option three
break;
case `n`:
// Do menu option "n"
break;
case `s`:
// Do menu option "s"
break;
}
If you need to handle numeric choices bigger than 9, you simply use a std::string as input field:
std::string choice; // <<<
std::cin >> choice;
in turn a switch statement cannot be used any more and you have to change it to an if/else if/else cascade:
if(choice == "1") {
// Do menu option one
}
else if(choice == "2") {
// Do menu option two
}
// ...
else if(choice == "42") {
// Do menu option fortytwo
}
else if(choice == "n") {
// Do menu option "n"
}
else if(choice == "s") {
// Do menu option "s"
}
For this, you'll need to read in the input as a string, then parse it to see if it's an alphabetic character or if it's a numeric string. Something along the lines of this (warning, I'm mostly a C programmer, so using C-strings instead of real strings):
#define INPUT_SIZE 8
char input[INPUT_SIZE]; // change size as appropriate
cin.getline(input, INPUT_SIZE);
if (cin.good())
if(input[0] >= '0' && input[0] <= '9') {
int value = atoi(input);
} else if(input[0] >= 'a' && input[0] <= 'z') {
char value = input;
}
}
Naturally, values need different names and actual code paths to deal with them, especially as C++ doesn't have a good built-in "either" type that I know of.
Alternatively, just treat everything as a character, assuming all numeric options are a single character, and test as '0' instead of 0.
Related
This is code for a 4x4 tic-tac-toe game. I am new to programming. I don't know how to ignore wrong input from the user. I tried searching Google, I found cin.clear() and cin.ignore(). They did work a little bit, but not fully working. For example, if the user enters 11111111 4 o as input, the program exits instead of ignoring this. How to ignore this input?
And what are cin.clear() and cin.ignore() doing?
char game[4][4];
int r, c;
char ans;
cin >> r >> c >> ans;
--r, --c;
if (!check_ok(r, c, ans)){
cout << "try again: select available ones only!!!\n";
--count;//count checks for 16 turns through while loop
}else{
game[r][c] = ans;
++count1;
}
bool Game::check_ok(int a, int b, char an) {
if (game[a][b] == ' ' && a < 4 && b < 4 && ((count1 % 2 == 0 && an == 'x') || (count1 % 2 != 0 && an == 'o'))){
game[a][b] = an;
return true;
}
else{
cin.clear();
cin.ignore();
return false;
}
}
OK. User input is hard.
Interactive user input is line based.
User inputs some values and then hits return. This flushes the stream and unblocks the readers to get the value from the stream. So you should design your input code to be line based.
The first question seems to be is all the input on one line or do they input the values with a return between each? You can determine this with some outut to the user then follow the rules defined by your instructions.
So lets do a line based input example:
do {
// Your instructions can be better.
std::cout << "Input: Row Col Answer <enter>\n";
// Read the user input. 1 Line of text.
std::string line;
std::getline(std::cin, line);
// convert user input into a seprate stream
// See if we can correctly parse it.
std::stringstream linestream(std::move(line));
// Notice we check if the read worked.
// and that the check_ok() returns true.
// No point in call check_ok() if the read failed.
if (linestream >> r >> c >> ans && check_ok(r, c, ans)) {
break;
}
std::cout << "Invalid Input. Please try again\n";
}
while(true);
i think instead of ignoring the wrong input you should limit the users input into the ideal inputs only. maybe an if statement could help
if(input != ideal_input)
{
cout>>"invalid input";
}
else
{
//progress in the game
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to make a program that asks the user whether they would like to continue to the next calculation. For some reasons whenever I enter y or Y, the program ends. However, if I use only one condition inside the if statement(without '||'sign), the code works fine. I just want to make sure that the user can enter both upper and lower case.
What's wrong with the code? Is there a better way to do this?
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
return true;
}else if(choice =='N'||choice =='n'){
return false;
}
}
return 0;
}
The return statement ends a function, in this case, this is the main, so it ends your program, whatever value you're returning.
If you only want to get out of your loop you have two solutions:
Use a boolean:
int main()
{
char choice;
bool run = true; //#stefaanv
while(run)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
run = false;
}
}
return 0;
}
Use break to exit your loop:
int main()
{
char choice;
while(true)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
break;
}
}
return 0;
}
But both these solution will consider any character entered exept N/n as "continue", if you want to avoid this:
int main()
{
char choice;
bool run = true;
while(run)
{
// Make your calculation
do{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
choice = tolower(choice);//Put your letter to its lower case
}while (choice != 'n' && choice != 'y')
if(choice =='n'){
run = false;
}
}
return 0;
}
For some reasons whenever I enter y or Y, the program ends
The return statement is used to return control(and sometimes an optional value), to a functions caller. When return is used inside the called function, the function is terminated. From cppreference.com:
[return] terminates [the] current function and returns [a] specified value to the caller function.
(emphasis mine)
You may be under the impression that the statement return true inside your while-loop is returning the Boolean value of true to your while condition. It is not.
If your end goal is to create a yes/no style program that ends when the user enters "No/no", then you can to make use of the continue and break statements, or use a do/while loop.
Using continue and break
The continue statement is used to immediately skip to the next iteration of a loop, for or while, terminating the current iteration. From cppreference.com:
Causes the remaining portion of the enclosing for, range-for, while or do-while loop body to be skipped.
Used when it is otherwise awkward to ignore the remaining portion of the loop using conditional statements.
(emphasis mine)
The break statement is somewhat similar to continue, but instead of breaking the current iteration and skipping to the next one, it immediately breaks the entire program out of the while loop returning control to the outer-scope. From cppreference.com:
Causes the enclosing for, range-for, while or do-while loop or switch statement to terminate.
Used when it is otherwise awkward to terminate the loop using the condition expression and conditional statements.
(emphasis mine)
After examining the information above, you can modify your program to make use of continue and break, instead of return:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculations?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
continue; // instead of returning, skip to the next iteration
// and ask again
}else if(choice =='N'||choice =='n'){
break; // return could be used here to break the while loop and
// terminate the program. But be explicit and use a statement specifically
// made for breaking out of loops
}
}
return 0;
}
Using a do/while loop
While the method above would work, I recommend using my second option-- a do/while loop. The do/while has the advantage o being shorter, and not having to make use of any kind of major control flow. From cppreference:
Executes a statement repeatedly, until the value of expression becomes false. The test takes place after each iteration.
If needed you could even add error checking to validate a users input:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
do { // do everything in the do block while...
cout <<"Would you like to perform other calculations?(Y/N)"<< endl;
cin >> choice;
if (choice != 'Y' and choice != 'y' and choice != 'N' and choice != 'n') // if needed add input
cout << choice << " is not a valid option. Try agian" << endl; // validation
} while (choice !='N' && choice !='n'); // the user input does not equal 'N'andr 'n'
return 0;
}
Output
Would you like to perform other calculations?(Y/N)
y
Would you like to perform other calculations?(Y/N)
Y
Would you like to perform other calculations?(Y/N)
n
References and Resources
cppreference.com
cplusplus.com
I just wrote some code and it works like a charm using "goto".
The code also included data validation as well. Many thanks to #Treycos.
int main()
{
char choice ='Y';
bool valid = true;
//some calculation
here:
int x =1+1;
cout<<x<<endl;
while(valid){
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N' || choice =='n'){
break;
}
if(choice =='Y'||choice =='y'){
goto here;
}
else if(choice != 'N'&& choice != 'n'&&choice != 'Y'&&choice != 'y'){
cout<<"Invalid input."<<endl;
valid = true;
}
}
return 0;
}
Output:
2
Would you like to perform other calculation?(Y/N)
y
2
Would you like to perform other calculation?(Y/N)
Y
2
Would you like to perform other calculation?(Y/N)
$
Invalid input.
Would you like to perform other calculation?(Y/N)
n
Process returned 0 (0x0)
For uppercase n:
2
Would you like to perform other calculation?(Y/N)
N
Process returned 0 (0x0)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to loop the whole codes If I press Y on "next customer"? and to reset the program just like the first try. Just type 0101 and 0307 on itemcode i put only some of my codes. define gotoxy is running only do while on "next customer " I think is the error?
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#define g gotoxy
main()
{
char back_, back;
float change, p0101 = 25.5, p0307=11,subtotal=0,total=0;
int y=9, quantity, itemcode, cash,discount;
clrscr();
do{
do{
g(1,8);
cout<<"Itemcode";
g(15,8);
cout<<"Quantity";
g(41,8);
cout<<"Price";
g(51,8);
cout<<"Subtotal";
g(62,8);
cout<<"Total";
g(1,y);
cin>>itemcode;
g(15,y);
cin>>quantity;
{
g(25,y);
if (itemcode == 0101){
cout<<"Yogurt(12 oz)";
subtotal = quantity * p0101;
}
else if (itemcode == 0307){
cout<<"Pumpkin (1000g)";
subtotal = quantity * p0307;
}
}
{
g(41,y);
if(itemcode == 0101){
cout<<"25.50";
}
else if (itemcode == 0307){
cout<<"79.75";
}
}
g(51,y);
cout<<subtotal;
total=total+subtotal;
g(62,y);
cout<<total;
subtotal=0;
g(72,8);
cout<<"Add item?";
g(72,y);
cin>>back;
y++;
if(back=='n'||back=='N'){
{
g(1,y+2);
cout<<"CASH: ";
cin>>cash;
}
if(cash>total){
{
g(1,y+3);
cout<<"[R]-REGULAR\t[D] - WITH DISCOUNT :";
}
cin>>discount;
g(1,y+4);
if(discount=='d'||discount=='D'){
(change=cash-(.8*total));
cout<<"Change: "<<change;
}
else{
change=cash-total;
cout<<"Change: "<<change;
}
}
else if(cash<total){
cout<<"Insufficient amount";
}
{
g(18,y+8);
cout<<"EXCHANGE OF ITEM TO ANOTHER TYPE AND SIZE IS ALLOWED,";
}
{
g(18,y+9);
cout<<"SUBJECT TO STANDARD PROVISIONS AND PRODUCT WARRANTY";
}
{
g(18,y+10);
cout<<" PLEASE PRESENT THIS RECEIPT";
}
{
g(15,y+12);
cout<<"Next Customer?";
cin>>back;
}
}
} while(back_=='Y'||back_=='y');
} while(back=='Y'||back=='y');
enter code here
getchar();
return 0;
}
You have some mistakes in programs.
take discount type int but use as a char
When your takes a integer value and after that takes a char, then between these, need to use getchar() because at the time of getting the integer, you press enter, so need to read it.
When you read a char, check that did you take a input before it, if takes, then read the newline character by getchar()
Check the code
#include<iostream>
#include<conio.h>
#include<stdio.h>
using namespace std;
int main()
{
char newCustomer, addItem,discount;
float change, p0101 = 25.5, p0307=11,subtotal=0,total=0;
int y=9, quantity, itemcode, cash;
do{
subtotal=0,total=0;
do{
cout<<"Itemcode: ";
cin>>itemcode;
cout<<"Quantity: ";
cin>>quantity;
{
if (itemcode == 101){cout<<"Yogurt(12 oz)";
subtotal = quantity * p0101;
}else if (itemcode == 307){cout<<"Pumpkin (1000g)";
subtotal = quantity * p0307;
}}
{
cout<<"Price: ";
if(itemcode == 101){
cout<<"25.50\n";
}else if (itemcode == 307){
cout<<"79.75\n";
}}
cout<<"Subtotal: ";
cout<<subtotal<<"\n";
total=total+subtotal;
cout<<"Total: ";
cout<<total<<"\n";
subtotal=0;
cout<<"Add item?";
cin>>addItem;
getchar();
if(addItem=='n'||addItem=='N'){
{
cout<<"CASH: ";
cin>>cash;}
getchar();
if(cash>total){
{
cout<<"[R]-REGULAR\t[D] - WITH DISCOUNT :";}
cin>>discount;
char c = getchar();
if(discount=='d'||discount=='D'){(change=cash-(.8*total));
cout<<"Change: "<<change<<"\n";}
else{change=cash-total;cout<<"Change: "<<change;}
}
else if(cash<total)
{cout<<"Insufficient amount";}
{
cout<<"EXCHANGE OF ITEM TO ANOTHER TYPE AND SIZE IS ALLOWED,";
}
{
cout<<"SUBJECT TO STANDARD PROVISIONS AND PRODUCT WARRANTY";}
{
cout<<" PLEASE PRESENT THIS RECEIPT\n";} {
cout<<"Next Customer?";cin>>newCustomer;char c = getchar();}
}
}while(addItem=='Y'||addItem=='y');
}while(newCustomer=='Y'||newCustomer=='y');
return 0;
}
I cannot see where you input into back_ but you have cin>>back; twice. Could this be your error? Your control structures are hard to follow.
You have, essentially,
do {
do {
// input some stuff for an item
cout<<"Add item?";
cin>>back;
if(back == 'n' || back == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>back;
}
} while (back_=='y' || back_=='Y')
} while (back=='y' || back == 'Y')
You defined back_ but never initialized it or used it in your code so when while (back_=='y' || back_=='Y') comes along, even when you press 'y', the loop never loops.
If you were to change the code to:
do {
do {
// input some stuff for an item
cout<<"Add item?";
cin>>back;
if(back == 'n' || back == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>back_;
}
} while (back_=='y' || back_=='Y')
} while (back=='y' || back == 'Y')
The program would certainly loop again if you pressed 'y' but you would get some interesting behavior when you pressed 'n' for "Add item?" and 'y' for "Next Customer?". I predict the program will close prematurely. Better to have:
char new_customer, add_item
do {
//---This is the outer loop---//
do {
//---This is the inner loop---//
// input some stuff for an item
cout<<"Add another item?";
cin>>add_item;
if(add_item == 'n' || add_item == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>new_customer;
}
//---End of the inner loop---//
} while (add_item=='y' || add_item=='Y')
//---End of the outer loop---//
} while (new_customer=='y' || new_customer=='Y')
This way the inner loop breaks when you press 'n' at "Add Item?" and the outer loop breaks when you press 'n' at "Next Customer?", effectively ending the program. Pressing 'y' at either will continue their respective loops.
Other odd behavior can come from
Pressing anything other than 'y' or 'n' at decision points
Inputting anything other than numbers into variables that are used to calculate prices and the such
Not formatting your output into the price fields with $ or having two decimal places for money
The first two can be fixed by reading everything in as strings and then parsing it out character by character to check for valid input and then converting the appropriate strings into a numbers using built-in C++ functions. The last one can be fixed with a little fancy calculations on the data with the % (modulus) operator to see if the values end with a zero or not. Just some ideas.
Looks like it mostly works, except for that one major error.
Assume all variables exist (didnt bother declaring them all here)
if(input=='R') goto restart;
if(input=='X') exit(0);
if(input=='D') moveRight(edgeLength, board, score);
if(input=='S') moveDown(edgeLength,board, arrSize);
if(input=='A') moveLeft(edgeLength,board, arrSize);
if(input=='W') moveUp(edgeLength,arrSize,board);
if(input=='P')
{
cin>> number>>position;
board[position]=number;
}
This input is put into a loop, so the user is asked for input so long as this game is in play.
My goal is to allow for input such as
p 3 50
to place the number 50 at index position 3.
With my current code, I have to type 'p' press enter, then the next two numbers.
However, id like the program to detect 'p 3 50' (enter) in one go, as 'D'(enter) signifies moveRight.
I hope I'm being clear in my question.
cin >> input >> number >> position;
if(input=='R') goto restart;
else if(input=='X') exit(0);
else if(input=='D') moveRight(edgeLength, board, score);
else if(input=='S') moveDown(edgeLength,board, arrSize);
else if(input=='A') moveLeft(edgeLength,board, arrSize);
else if(input=='W') moveUp(edgeLength,arrSize,board);
else
{
//whatever statements for last condition;
}
If you want to capture all three input at once, you can get the input first, then execute the respective actions according to the received inputs.
Added: Using if or else-if depends on situation. From what I see here in your code snippet, else-if is better than if because you can only have one input type everytime. Once matching character is found, (example 'D'), it will stop reading the codes below (which should be the way as it is unnecessary to check the rest of the conditions whether input is 'S' or 'A' or 'W' anymore since you already got the input). Makes your code fun slightly faster too, by preventing unnecessary checking on the conditions.
Proof Of Concept:
//Example
void fncOne()
{
cout << "This is function one" << endl;
}
void fncTwo()
{
cout << "This is function two" << endl;
}
int main()
{
char input;
int number, position;
cin >> input >> number >> position;
if (input == 'A') fncOne();
else if (input == 'B') fncTwo();
}
Input: A 3 5
Output: This is function one
Well, first you're going to want to get user input as a string rather than individual types.
std::string input;
std::cin >> input;
then you'll want to parse that string based on how many words for key words/characters.
e.g.
std::vector<std::string> words;
std::stringstream stream(input); std::string temp;
while(stream >> temp)
words.push_back(temp);
if(words.size() == 3){
if(words[0][0] = 'p'){
int number = std::stoi(words[1]);
int position = std::stoi(words[2]);
board[position] = number;
}
else
... get input again ...
}
else if(words.size() > 1){
... get input again ...
}
else{
char c = words[0][0];
if(c == 'w')
moveUp(edgeLength,arrSize,board);
else if(c == 's')
moveDown(edgeLength,board, arrSize);
else if(c == 'a')
moveLeft(edgeLength,board, arrSize);
else if(c == 'd')
moveRight(edgeLength, board, score);
else if(c == 'x')
exit(0);
else if(c == 'r')
goto restart;
else
... get input again ...
}
Of course this is only one way if you want to type one string then press enter only once.
I am new to C++ and am making a simple text RPG, anyway, The scenario is I have a "welcome" screen with choices 1-3, and have a simple IF statement to check them, here:
int choice;
std::cout << "--> ";
std::cin >> choice;
if(choice == 1) {
//..
That works fine, but if someone enters a letter as selection (instead of 1, 2 or 3) it'll become "-392493492"or something and crash the program. So I came up with:
char choice;
std::cout << "--> ";
std::cin >> choice;
if(choice == 1) {
//..
This works kinda fine, but when I enter a number it seems to skip the IF statements completely.. Is the char "1" the same as the number 1?
I get a compiler error with this (ISO-CPP or something):
if(choice == "1")
So how on earth do I see if they entered 1-3 correctly!?
1 is an int
'1' is a char
"1" is a char array
I guess you want to compare with '1'.
Choice doesn't become "-392493492" or something, it starts as that value (you didn't initialise it, so the initial value is unspecified) and is never set to anything else because the >> fails. You should check that such operators succeed, which is quite easy to do:
if (std::cin >> choice) {
switch (choice) {
case 1: // ...
case 2: // ...
case 2: // ...
default: // report error
}
}
Unfortunately 1 and '1' are not the same.
Look up your favorite ASCII table to know the integer value that represents the character "1" and you'll see it for yourself: '1' is mapped to 49.
There is another issue with this code "" denotes a C-string (const char*) whereas '' denotes a single character.
Here is your code reworked:
char choice = 0;
if (cin >> choice) // check success
{
switch(choice) // choose
{
case '1': { /**/ break; }
case '2': { /**/ break; }
case '3': { /**/ break; }
default:
cout << choice
<< " is not a valid choice, please press 1, 2 or 3 and Enter"
<< endl;
}
}
I switched to switch because it's more natural than a chain of else-if for generic enumeration.
if(choice == '1')
And to answer your question, the ascii valyue for 1 is not equal to 1, but is equal to 49:
'1' == 49
choice is a char so you should use '1' to check. "1" represents a string with 1 character in it.
A value in double quotes is interpreted as a string (of type char*, which is incompatible with a char), while in single quotes it is interpreted as a char:
if(choice == '1')
The integer representation of the char'1' is not 1, but 49 (in ASCII). So you could also write
if(choice == 49)
Also, you should have an else branch to display an error message or something, and prevent the program from continuing in case an invalid input has been entered.