Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 months ago.
Improve this question
The folowing code tells user to input their age, it is set to be input interger between 0 and 120, it is capable to deal with wrong input like 'M' or 133 or -1. Warning message goes like this:Warning message
case 1: // input age
cout << "Enter your age: ";
cin >> age;
if(age <= 0 || age > 120){ // if the input type or number was wrong, it goes here
while(1){
cout << "Invalid input! Please enter again" << endl << ">>>";
age = -1;
cin >> age;
if(age > 0 && age <= 120) {break;}
}
}
However, it'll go wrong if I input something like \ or [.
Repeating Warning message
How can I solve this?
By emptying the keyboard buffer before a new entry.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int age;
cout << "Enter your age: ";
cin >> age;
while(age <= 0 || age > 120)
{
cout << "Invalid input! Please enter again" << endl << ">>>";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> age;
}
return 0;
}
lets walk through this.
You type in something wrong and enter the if clause.
In here you enter the while loop and ask the user again for a input. This input is instantly answered because there is still something in the input stream.
Therefore you need to flush the cin stream before asking again for an input (You can place the flush in for example line 4).
You should be able to clear the stream with a command like this:
How do I flush the cin buffer?
Unfortunately I'm not able to test that out by myself but you can give it a try and I hope it helps!
Related
This question already has answers here:
How do I prevent a runaway input loop when I request a number but the user enters a non-number?
(6 answers)
Closed 4 years ago.
In the below code, if anything that is not a number is entered, the program seems to continuously enter that input automatically. It translates the input to "0" since n is an int, but it does not act the same way if "0" is actually entered.
I have looked up and down and there does not seem to be a reliable way to say something like
if (n != int){cout << "invalid";}
I guess my last resort would be to just allow 0 to be a valid input, but I was hoping there's another way.
int n;
cout << " \nPlease enter a number 1 to 99,999: ";
cin >> n;
while (n < 1 || n> 99999)
{
cout << "\nThat is an invalid entry!"
<< "\nPlease enter a number 1 to 99,999: ";
cin >> n;
}
When you try to extract a value from an std::istream like std::cin and extraction fails, all data remains in the stream for the next input operation. If the same extraction is then tried again, it will again get garbage and fail. And so on.
To repeat trying to extract an int from a stream if extraction fails, you should remove all garbage before you try again:
#inlcude <limits>
#include <iostream>
// ...
int n;
while(!(std::cin >> n)) { // extraction failed
std::cin.clear(); // clear error flags
// ignore everything left in the stream up to a newline:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Combining that with limiting the value to a number between 1 and 99999:
#include <limits>
#include <iostream>
int main()
{
int n;
std::cout << "Please enter a number 1 to 99999: ";
while (!(std::cin >> n) || n < 1 || 99999 < n) {
std::cerr << "Input Error!\n\n";
std::cin.clear(); // clear error flags
// ignore everything left in the stream up to a newline:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
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
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
//this program will let the user input their assignment score and see their letter grade
int main() {
int score;
cout << "Input your score: ";
//to make the while loop
int x = 1;
while (x == 1) {
cin >> score;
if (score >= 90){
cout << "\nA";
break;
}
else if (score >= 80) {
cout << "\nB";
break;
}
else if (score >= 70) {
cout << "\nC";
break;
}
else if (score >= 60) {
cout << "\nD";
break;
}
else if (score >= 0) {
cout << "\nF";
break;
}
else
cout << "\nInvalid input";
}
}
I'm trying to write a program that let the user input their score for an assignment and display their resulting letter grade. If the user input is not a valid score, it prints "Invalid input" and should ask for user input again. However, when I actually run the program and type in an invalid value, it goes into an infinite loop of printing "Invalid input". Why is this? Thanks in advance.
When the user enters invalid input, cin >> score fails and leaves an error flag set on the stream.
Subsequent read operations just don't do anything until you clear that flag with std::basic_ios::clear().
Furthermore, since the read failed, score has some unspecified value (as you did not initialise it), and apparently on your test runs that unspecified value happens not to match any of those continues, so you never hit a break.
Instead of just:
std::cin >> score;
Try this:
if (!(cin >> score)) {
// If reading into an int failed, we come here
cout << "Invalid value! Try again" << endl;
// Clear error flag
cin.clear();
// Restart the loop
continue;
}
You may also need to ask the stream to eat up newlines in the input buffer. If you get the "Invalid value!" message twice, look up on SO how to do that.
you set x=1 and check if x==1. For the compiler it seems that it could be an infinite loop because it's unsure if a break would happen, that's why it's only a Warning and not an Error. For that behaviour you don't even need to vast the variable x , you could use while(true) too.
This question already has an answer here:
C++ CIN cin skips randomly
(1 answer)
Closed 8 years ago.
Sorry, I dont know how to ask this better, I'm a really novice programmer and I'm not looking for you to do my homework, but I want to understand why this keeps happening.
int inputScores(string names [], double scores [])
{
int count = 0; // counter variable for number of student records in array
char again; // To check if user has more data
do
{
cout << "Enter student's name: ";
getline(cin, names[count]);
cout << "\nEnter student's score: ";
cin >> scores[count];
count++;
cout << "\nDo you have more student records to enter?(Y/N): ";
cin >> again;
}while(again == 'y' || again == 'Y');
when I run this code and call the function this keeps happening and I dont know how to fix it:
Enter student's name: Arthur
Enter student's score: 100
Do you have more student records to enter?(Y/N): y
Enter student's name:
Enter student's score:
it skips the "enter student's name question" (doesnt let me type anything) and goes straight to the next question.
The reason the program does not wait for you to enter the student's name is there is a \n still left in the input stream after you read again in the line:
cin >> again;
When the program reaches:
getline(cin, names[count]);
it just reads the an empty line and moves on to the next line.
You need to use:
int maxCharsToIgnore = 100; // This seems large enough
// for your use case.
cin.ignore(maxCharsToIgnore,'\n');
right after
cin >> again;
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to validate numeric input C++
How do you do the following:
while (iNumberOfPlayers <2 || iNumberOfPlayers >5)
{
cout << "Enter number of players (1-4): ";
cin >> iNumberOfPlayers;
cin.clear();
std::string s;
cin >> s;
}
After looking at the loop I'm thrown in, it looks like cin isn't getting reset (if I put in x) cin reads X again as long as I'm in the while loop. Guessing this is a buffer issue, any way to clear it?
I then tried:
while (iNumberOfPlayers <2 || iNumberOfPlayers >5)
{
cout << "Enter number of players (1-4): ";
cin >> iNumberOfPlayers;
cin.clear();
cin.ignore();
}
which works except it reads everything 1 at a time. If I put in "xyz" then the loop goes through 3 times before it stops to ask again.
If the input is not valid, the fail bit is set on the stream. The ! operator used on a stream reads the fail bit (You could also use (cin >> a).fail() or (cin >> a), cin.fail()).
Then you just have to clear the fail bit before trying again.
while (!(cin >> a)) {
// if (cin.eof()) exit(EXIT_FAILURE);
cin.clear();
std::string dummy;
cin >> dummy; // throw away garbage.
cout << "entered value is not a number";
}
Please note that if you're reading from non-interactive input, this would become an infinite loop. So use some variation on the commented error-detection code.
The tricky thing is that you need to consume any invalid input as failure to read doesn't consume the input. The simplest solution to this is to move the call to operator >> into the loop condition and then read up to the \n if it didn't mange to read an int:
#include <iostream>
#include <limits>
int main() {
int a;
while (!(std::cin >> a) || (a < 2 || a > 5)) {
std::cout << "Not an int, or wrong size, try again" << std::endl;
std::cin.clear(); // Reset error and retry
// Eat leftovers:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}