Handling invalid user inputs in C++ [duplicate] - c++

This question already has answers here:
cin input (input is an int) when I input a letter, instead of printing back incorrect once, it prints correct once then inc for the rest of the loop
(2 answers)
How to test whether stringstream operator>> has parsed a bad type and skip it
(5 answers)
Closed 4 years ago.
I've been coding in C++ for all of a few days, so please talk to me like I'm a baby. With that out of the way,
I've made a short algorithm that asks a set of questions (to be answered 0 for no and 1 for yes) and stores the user's answer as an integer. Everything works as expected as long as the user only inputs integers (or, in one case, a string with no spaces).
But if the input doesn't match the variable type, the program immediately outputs this infinite loop that appears later in the program. That loop is supposed to print a question, wait for input, and then ask again if the answer isn't '1', but in the failure state it just prints the question without end. I can't see any reason why the previous questions would be connected to this. It doesn't happen on the questions that come after it, if that's a clue.
Here's a pared-down version of my code with, I hope, all the important information intact:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int answer1;
string answer1C;
int answer2;
int answer2B;
int score;
score = 0;
cout << "Question 1" << endl;
cin >> answer1;
if (answer1 == 1)
{
++score;
//some other questions go here
cout << "Question 1C" << endl;
cin >> answer1C;
if (answer1C.size() == 6)
{
++score;
}
}
cout << "Question 2" << endl;
cin >> answer2;
if (answer2 == 0)
{
cout << "Question 2B" << endl;
cin >> answer2B;
if (answer2B == 0)
{
--score;
}
while (answer2B != 1) //Here is the infinite loop.
{
cout << "Question 2B" << endl;
cin >> answer2B;
}
}
cout << "Question 3" << endl;
//and so on
return 0;
}
I would love to have it accept any input and only perform the ensuing steps if it happens to meet the specified conditions: for instance, in question 1.2, it only awards a point if the answer is a string of length 6, and otherwise does nothing; or in question 2.1, it repeats the question for any input that isn't '1', and moves on if it is.
But in any case whatsoever, I need it to do something else when it fails. Please help me figure out why this is happening. Thank you.

Related

(Total Beginner) Unsure why goto does not work in program [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 5 months ago.
Improve this question
Hey so I only started C++ 2 days ago, so please try to keep the answer simple, otherwise probably won't understand it, thanks!
I tried to make a basic program where a program asks for a word, then counts the letters in said word. It then tells asks if you want to know the letter in any given position of the letter. Im making this because I thought I would learn better if I just tried making something basic rather than endlessly watching videos on it.
I ran into a problem with the asking the user part of the code. I want to have it check whether the user typed Y or N, and if neither, repeat asking until either Y or N is inputted. I tried using goto, but I could not get it to work despite checking online tutorials on how it should work. If anyone could help that would be greatly appreciated :).
When run, it does the following: enter image description here
The code is below, thank you for reading:
#include <string>
using namespace std;
int main(){
string text; //variable for the word to be measured
int letter; //variable for the placement of the letter in word
string confirmation; //variable for Y or N
cout << "This program counts letters in a word \n\n";
cout << " Please type a word for me to count: \n\n";
cin >> text;
cout << "\nYour word has " << text.length() << " letter";
if (text.length()>1){
cout << "s"; // Checks whether to put an s at the end of the prev. sentence for a plural or not
}
cout << "\n\nThis is what you typed by the way: " << text << "\n\n";
cout << "Would you like me to find the letter in any given position in the word? \n\n If yes, type Y. If no, type N: \n\n";
cin >> confirmation;
check:
if (confirmation == "Y"){ //Loops until one of these are fulfilled
cout << "What position's letter would you like me to find? \n\n";
cin >> letter;
cout << "\n" << text[letter-1] << "\n\n";
cout << "Thanks for using me, have a nice day";
} else if (confirmation == "N"){
cout << "\nAlright have a nice day";
} else {
goto check;
}
return 0;
}
First, goto-Syntax is something you do not need to learn as a beginner. In 99.99% there are better alternatives than using goto, so until you are very advanced, just pretend that goto does not exist in C++.
Second, the goto in your code works. It is just that if the user answers something different than "Y" or "N", your code will infinitely loop between the label check: and the goto check statement, as there is no way that confirmation can change in between.
Last, here is an example how to better do this, using a while-loop.
cout << "Would you like me to find the letter in any given position in the word? \n\n If yes, type Y. If no, type N: \n\n";
cin >> confirmation;
while (confirmation != "Y" && confirmation != "N") { //Loops until one of these are fulfilled
cout << "Please answer Y or N.\n";
cin >> confirmation;
}
if (confirmation == "Y"){
cout << "What position's letter would you like me to find? \n\n";
cin >> letter;
cout << "\n" << text[letter-1] << "\n\n";
cout << "Thanks for using me, have a nice day";
} else {
cout << "\nAlright have a nice day";
}

For Loops (C++)

Assignment:
The program should ask the user to enter a positive number and display all numbers from 1 to the input value. If the number is not positive, an error message should show up asking the user to re - enter the number.
My specific problem:
For my program, if the user enters an incorrect number and then re - enters a positive number, it does not display all the numbers from 1 to the input value. The program just ends.
#include <iostream>
using namespace std;
int main()
{
int userChoice;
int i = 1;
cout << "Enter a positive integer" << endl;
cin >> userChoice;
if (userChoice > 0)
{
for (i = 1; i <= userChoice; i++)
{
cout << "Loop 1:" << endl;
cout << i << endl;
}
}
else if (userChoice < 0)
cout << "Please re - enter" << endl;
cin >> userChoice;
system("pause");
return 0;
}
You need some sort of loop at the top of your program, that keeps asking for input until the user provides something valid. It looks like a homework assignment, so I will provide pseudo-code, not something exact:
std::cout << "Enter a number:\n";
std::cin >> choice;
while (choice wasn't valid) { // 1
tell the user something went wrong // 2
ask again for input in basically the same way as above // 3
}
// after this, go ahead with your for loop
It is actually possible to avoid the duplication here for step 3, but I worry that might be a little confusing for you, so one duplicated line really isn't such a big problem.
As an aside, you may wish to reconsider your use of what are often considered bad practices: using namespace std; and endl. (Disclaimer - these are opinions, not hard facts).

error when calling char to allow user to enter choice [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 6 years ago.
Improve this question
I am writing a simple text game in C++. The user has the option of choosing the left room or the right room. I did have this set up as an int statement: enter 1 for left, enter 2 for right. Now I would like to have the user enter left for left room, right for right room.
I replaced the int with char, but I am getting an error.
#include <iostream>
using namespace std;
int main() {
char decision;
cin >> decision;
if (decision == left) {
cout << "went left" << endl;
}
return 0;
}
Error: comparison between pointer and integer
char stands for a single character - what you need is a string (multiple characters).
when you actually have the user's value in decision you need to compare it to the string "left" rather than just left which the compiler tries to interpret as a symbol (like a variable name).
All in all:
#include <iostream>
#include <string>
using namespace std;
int main() {
string decision;
cin >> decision;
if (decision == "left") {
cout << "went left" << endl;
}
return 0;
}
the easiest way use strcmp:
#include <iostream>
int main()
{
char decision[50] = "";
std::cout << "Decision: ";
std::cin.get(decision, 50, '\n');
if( !(strcmp(decision, "left")) )
std::cout << "left";
else
if( !(strcmp(decision, "right")) )
std::cout << "right";
else
std::cout << "bad input!" << std::endl;
std::cout << std::endl;
return 0;
}
you should also make no difference between lowercase and uppercase because if a user enters "Left" instead "left" then it won't work

Where am I going wrong re: data validation c++ [duplicate]

This question already has answers here:
Using getline(cin, s) after cin [duplicate]
(13 answers)
Closed 7 years ago.
I have some code:
I wish to take in an ID, make sure it's of 8 chars in length, make sure each digit is a number, and continue to ask until they give the correct input. BEFORE SOMEONE MARKS THIS DOWN, i researched and tried to look at answers given :c
I don't get why it says the id I enter 00000002 is an Invalid ID according to my code. It's not working. can anyone help?
void Student::getData(){
string id_;
cout << "lastName?" << endl;
cin >> lastName;
cout << "firstName?" << endl;
cin >> firstName;
cout << "ID?" << endl;
while(getline(cin,id_) && id_.size() != 8){
cout << "Invalid ID" << endl;
}
while(getline(cin,id_) && id_.size() != 8){
Here getline() just gets the newline left over from the previous line of input. Add a line to ignore the rest of the line before that.
cin.ingore(std::numeric_limits<std::streamsize>::max(), '\n');
while(getline(cin,id_) && id_.size() != 8){

Why does the loop loop itself when "else" is triggered? Is this because of things called memory allocation? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm just a beginner and trying out some code that my teacher taught us to use and things from the textbook.
This program is designed to be for the user to enter in their name and enter in the password as what the system asks them to put down.
Can somebody explain to me why this loop keeps looping itself infinitely when else is triggered?
Also, what does the cin.ignore do to the memory of the char name? Why is 80 better than 20?
AND, why aren't the random numbers actually random? Every time I run it, the numbers are the same.
Thank you all so much!
#include <iostream>
#include <cstdlib>
using namespace std;
int main ()
{
char name[20];
int pwd, rand1, rand2;
for (int i=0;i<1; i++)
{
cout<<"Name: ";
cin.get(name, 20);
cin.ignore(80, '\n');
cout<<endl;
srand(rand() % 1000);
rand1 = (rand() % 21);
rand2 = (rand()%6);
cout<<"Password: "<<rand1<<"*"<<rand2<<"= ";
cin>>pwd;
if(pwd == rand1*rand2)
{
cout<<endl<<"Welcome to our main page, "<<name<<"."<<endl;
}
else
{
cout<<"Wrong password, type again." <<endl;
i--;
}
}
return 0;
}
First up formatting of code will help you understand better.
Also avoid using namespace std, its bad practice and clutters the global scope with names. Instead use using std::xxxx if you dont want to write std::cout, std::cin, etc every time.
Reformatted code:
#include <iostream>
#include <cstdlib>
using std::cin;
using std::cout;
using std::endl;
int main ()
{
char name[20];
int pwd, rand1, rand2;
for (int i = 0; i < 1; i++) {
cout << "Name: ";
cin.get(name, 20);
cin.ignore();
cout << endl;
srand(rand() % 1000);
rand1 = (rand() % 21);
rand2 = (rand() % 6);
cout << "Password: " << rand1 << "*" << rand2 << "= ";
cin >> pwd;
cin.ignore();
if(pwd == rand1*rand2) {
cout << endl << "Welcome to our main page, " << name << "." << endl;
} else {
cout << "Wrong password, type again." << endl;
i--;
}
}
return 0;
}
Secondly as you can see in the above code the line cin.ignore(); has been added after cin >> pwd. Before your code was getting cin >> name, leaving '\n' in the input, ignoring '\n', getting cin >> pwd, leaving '\n' in input, looping and reading input as empty with a '\n', leaving another '\n' in input, first '\n' is removed by ci.ignore(), second '\n' read by cin >> pwd, ... etc. Or at least this is how I understand it.
Somebody has answered the first question:Because when you i--, the i in the for loop keeps decreasing and then increasing.-By Gasim
Then, if your input is longer than 20, the program may stop. So you need cin.ignore(80, '\n') to ignore the excess input. The number 80 is just a big number. You can replace it with another number-only if it's big enough.
You are supposed to use srand with time. srand(time(null)) may help.