How do I allow different amounts of input in c++ - c++

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.

Related

How to ignore wrong cin input in C++?

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
}

Having to hit enter twice with cin.getline()

I know for a fact similar questions have been asked before but I really can't figure out what's wrong with my code specifically. For some reason if I input "n" I have to press enter twice. But if I input "y", everything works fine and the code moves to the next section. My code is as follows:
do{
try {
if (test) cout << " Re-enter: ";
test = false;
getline(cin, choice);
checkinput(choice);
}
catch (int flag) {
if (flag == 1){ cout << "Error: Input must be y or n."; test = true; }
}
} while (test);
and the checkinput function is as follows:
// function for checking the input of y/n
string checkinput(string c) {
if (c != "Y" && c != "y" && c != "N" && c != "n") {
throw 1;
}
if (cin.fail()) throw 1;
return c;
}
I think you are trying to do too much here. You can simplify this.
There is no need to throw and catch exceptions inside checkinput. Since there is only two cases you can use a boolean. Secondly, you are returning c. I don't know why you are doing that, it isn't being used. You should instead, return a boolean.
checkinput becomes:
bool checkInput(string c) {
if (c.length() > 1)
return false;
return c == "Y" || c == "y" || c == "N" || c == "n";
}
Now you can simplify the do-while and remove the try statement. Additionally, there is no need for the test variable now since we are successfully grabbing any input:
int main() {
string choice = "";
do {
cout << "Enter yes or no (y/n): ";
getline(cin, choice); // or cin >> choice;
bool check = checkInput(choice);
if (!check)
cout << "Error: Input must be y or n." << endl;
} while (true);
}
You may also simplify this further but that will be at the cost of readability. Good luck!

Get yes/no in console always fails

I'm trying to make a program that will run over and over again, provided the user says yes every time. Unfortunately, it doesn't seem to recognize when I input yes or no into it, and always does the default "Come again?" message. This is the code I'm using to get the input from the console:
bool getYN(){
bool confirmed = 0;
bool answer = 0;
string input;
while(!confirmed){
getline(cin, input, '\n');
transform(input.begin(), input.end(), input.begin(), toupper);
if(input.c_str() == "Y" || input.c_str() == "YES"){ //If the user says yes
confirmed = 1;
answer = 1;
} else if(input.c_str() == "N" || input.c_str() == "NO"){ //If the user says no
confirmed = 1;
answer = 0;
} else { //If the user says something else entirely
printf("\nCome again? (Y/N) ");
};
};
return answer;
};
I have included <string> and <algorithm>. For some reason, it always acts like it's not getting y/yes or n/no when I type them in. It just keeps asking me to answer again.
if(input.c_str() == "Y" || input.c_str() == "YES"){ //If the user says yes
confirmed = 1;
answer = 1;
} else if(input.c_str() == "N" || input.c_str() == "NO"){ //If the user says no
confirmed = 1;
answer = 0;
}
You should not be doing c-string comparisons like this. You're taking the address of a char and comparing against the address of a text-allocated object. Of course the comparison is going to return false.
With c++ strings, simple operator== comparisons are valid:
if(input == "Y" || input == "YES"){ //If the user says yes
confirmed = 1;
answer = 1;
} else if(input == "N" || input == "NO"){ //If the user says no
confirmed = 1;
answer = 0;
}
#include <iostream>
#include <string>
using namespace std; // For speed
int main()
{
bool saidYes = false;
string input;
while (!saidYes)
{
cout << "Input yes or no: ";
getline(cin, input);
if (input == "no" || input == "n" || input == "NO")
{
saidYes = true; // breaks the loop
}
if (input == "y" || input == "Y" || input == "yes" || input == "YES")
{
saidYes = false;
}
}
return 0;
}
You can use the above example to eliminate a huge portion of unnecessary code, I chose not to add the else statement but it will work if you add that here as well.
You can also condense this code even further but this was only intended to be a simple example as to how to better get this working for you!
As it was said above you can use == to compare the strings, if you're coming from certain other languages it can be an annoying change to get used to lol.
I have included string and algorithm. For some reason, it always acts like it's not getting y/yes or n/no when I type them in. It just keeps asking me to answer again.
algorithm is not required for what you're trying to do, and your making the reading and acceptance of the string input much more difficult than it needs to be.
If you look above you'll see the string input; This is going to be your variable that you can use to store the user input string into.
You'll also notice getline(cin, input); This is what you can use to "read" the string that the user enters when they're prompted to.
#Kelvin Shadewing My initial answer was only directed at your Question, this next example is directed to your comment to me below!
So you've got quite a few options but assuming that you want the user to input either yes or no and depending on the input you want to produce a specific result while ensuring that the user is prompted over and over again to input either yes or no all you have to is modify my original answer like so.
#include <iostream>
#include <string>
using namespace std; // For speed
int main()
{
bool saidYes = false;
string input;
while (!saidYes)
{
cout << "Input yes or no: ";
getline(cin, input);
if (input == "no" || input == "n" || input == "NO")
{
saidYes = true;
cout << "you said no" << endl;
/* breaks the loop by changing the
bool (true or false flag) to true, if you want to produce a specific result,
whether it's a simple output statement or a function call you can put it here
*/
}
else if (input == "y" || input == "Y" || input == "yes" || input == "YES")
{
saidYes = true;
cout << "You said yes" << endl;
/* breaks the loop by changing the
bool (true or false flag) to true, if you want to produce a specific result,
whether it's a simple output statement or a function call you can put it here
*/
}
else saidYes = false;
}
return 0;
}
I've modified my code based on the current best answer, but I've also optimized it so that confirmed is no longer necessary.
bool getYN(){
bool answer = 0;
string input;
while(!answer){
getline(cin, input, '\n');
transform(input.begin(), input.end(), input.begin(), toupper);
if(input == "Y" || input == "YES"){
answer = 2;
} else if(input == "N" || input == "NO"){
answer = 1;
} else {
printf("\nCome again? (Y/N) ");
};
};
return answer - 1;
};
Small optimization, sure, but every little bit counts.

I dont know why i cant loop the whole code? when i press y on "next customer" [closed]

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.

C++ Load Document Error. Trying to test

I'm working on a project from class and it's a text analysis project. We're supposed to load a document into the program and basically read data from it. Ex: (word count, sentence count, etc.). For some reason, my first function isn't working correctly: my loadDocument function is supposed to load the document into the program.
Here is the code in main to call that function:
case 1: // Load Document
{
string inputLoc;
cout << "Please input the document name:" << endl;
cin >> docName;
myDocs[docCount].setName(docName);
myDocs[docCount].id = docCount;
cout << "Input Location: " << endl;
cin >> inputLoc;
myDocs[docCount].loadDocument(inputLoc);
docCount++;
break;
}
I have docName initialized outside of the case - before it.
Here is my loadDocument in side my Document class:
void Document::loadDocument(string name)
{
ifstream myFile(name);
int numOflines = 0;
string theLine;
char words;
while (myFile.get(words))
{
switch (words)
{
case '.':
numOflines++;
break;
case '?':
numOflines++;
break;
case '!':
numOflines++;
break;
}
}
lineCount = numOflines;
setLineCt(numOflines);
arr = new Line[lineCount];
myFile.close();
char theChar;
ifstream myFile2(name);
int key = 0;
if (myFile2.is_open())
{
for (id = 0; id < lineCount; id++)
{
while (theChar != '.' || theChar != '!' || theChar != '?')
{
myFile2 >> noskipws >> theChar;
theLine[key] = theChar;
key++;
}
myFile2 >> theChar;
arr[id].setStr(theLine);
}
}
}
I just wanted to know if my loadDocument has any evident bugs? For some reason, it's not actually loading a document into the program. For the input location, I typed in the exact file location of a text file that I want to input. For ex: C:\Users\Documents------. After I input that, my program just goes into an infinite loop.
Is my loadDocument doing what it's supposed to do? It's supposed to open a document and extract the number of sentences from it as well as number of words.
Also, am I testing it correctly by typing in that file location like that? I'm new to file input/output sorry.
Your while() loop is incorrect:
while (theChar != '.' || theChar != '!' || theChar != '?')
|| is not the right conditional operator here. If one condition is false, the two others will be true, thus leading to the infinite loop. You have to use &&:
while (theChar != '.' && theChar != '!' && theChar != '?')