loop repeats without prompting the user again? - c++

I have this snippets of code from my original long program, and as much as it looks simple, it doesn't work correctly! I am brand-new to c++ language, but I know in Java that would be the way to do it (Regardless of the syntax).
Simply put, this should ask the user for an input to answer the following multiplication (5*5), however, it should also check if the user entered a wrong input (not number), keep asking the user again and again... Somehow, it keeps running forever without taking a new input!!
I hope to get, not only an answer, but also a reason for such an error!
int main() {
int userAnswer;
bool isValidAnswer = true;
cout << 5 << " * " << 5 << " = ";
cin >> userAnswer;
cin.ignore();
do {
if (cin.fail()) { //user input is not an integer
cout << "Your answer is not valid! Please enter only a natural number: ";
cin >> userAnswer;
cin.ignore();
} else {
isValidAnswer = false;
}
} while (isValidAnswer);
return 0;
}

Well you need to clear the error state before accepting new input. Call cin.clear() then cin.ignore() before trying to read input again.
I would do something like.
cout << "Enter a number: ";
cin >> number;
while(cin.fail())
{
cin.clear();
cin.ignore(1000, '\n'); //some large number of character will stop at new line
cout << "Bad Number Try Again: ";
cin >> number;
}

First, cin.fail() is not going to adequately check if your answer is a natural number or not with the type set to int (could also be negative).
Second, your boolean isValidAnswer is really checking if it's is an invalid answer.
Third (and most importantly), as another answer suggests, you should put in cin.clear() to clear the failure state, and then followed by cin.ignore(), which will remove the failed string from cin.
Fourth, cin will only check if an int exists somewhere in the string. You'll need to perform your own string comparison to determine if the entire input is a int (see answer below, based on this answer).
Updated:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
bool isNum(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
int main() {
int userAnswer;
string input;
bool isInvalidAnswer = true;
cout << 5 << " * " << 5 << " = ";
while (isInvalidAnswer) {
if (!(cin >> input) || !isNum(input)) {
cout << "Answer is not a number! Please try again:\n";
cin.clear();
cin.ignore();
}
else {
userAnswer = atoi(input.c_str());
if (userAnswer < 0) { //user input is not an integer
cout << "Answer is not a natural number! Please try again:\n";
} else {
isInvalidAnswer = false;
}
}
}
cout << "Question answered!\n";
return 0;
}

Related

c++ why the second input is ignored?

I need to check whether digit was entered and if not, ask for correct input.
Second input is ignored for some reason.
(There should be "while" instead of "if" in the final version, but I replaced it to "if" for debug to avoid eternal loops)
#include <iostream>
int main()
{
int number = 0;
std::cout << "Please enter some digit:\n";
std::cin >> number;
if (!isdigit(number))
{
std::cout << "Wrong input, please enter digit\n";
std::cin >> number;
}
}
There is no point in using isdigit() on an int, it only makes sense to use it with a char, as it looks for characters between '0'..'9', not integers between 0..9.
If cin >> number fails to read in a valid integer, it will put the stream into a failure state, which blocks further input. You must clear() that state, and also ignore() the erroneous input, before you can read in further input.
Try something more like this:
#include <iostream>
#include <limits>
int main()
{
int number;
std::cout << "Please enter a single digit:\n";
do
{
if (std::cin >> number)
{
if (number >= 0 && number <= 9)
break;
std::cout << "Wrong input, please enter a single digit\n";
}
else
{
std::cout << "Wrong input, please enter a valid digit\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
while (true);
std::cout << "You entered: " << number << std::endl;
}

cin buffer Issues in C++

I'm learning C++, so I don't fully understand what's going on with my code here, but from what I've been able to glean, it seems like it could be some kind of buffer issue.
#include <stdio.h>
#include <vector>
#include <iostream>
#include <typeinfo>
using namespace std;
bool stopRun = true;
int height, average, total, count;
vector <int> heights;
int main ()
{
while (stopRun)
{
cout << "Enter a height, or 'end' to quit: ";
cin >> height;
if (typeid(height).name() == "i")
{
heights.push_back(height);
cout << heights[0];
count++;
}
else if (typeid(height).name() == "i")
{
cout << "\nPlease enter an integer: ";
continue;
}
if (count == 5)
{
stopRun = false;
}
}
for (int i = 0; i < heights.size(); i++)
{
total += heights[i];
cout << "\nTotal: " << total;
}
return 0;
}
For some reason, this code will continuously output: "Enter a height, or 'end' to quit: ". In an earlier version, it would output: "Enter a height, or 'end' to quit: Please enter an integer: ".
What I think is going on is that my "cin >> height;" line is pulling in the output from "Please enter an integer: " and treating it as my input, which identifies it as not being of type integer, which starts the infinite loop.
How do I clear the input buffer so that it doesn't bring in cout statements? Or is that even the issue I'm experiencing here?
Thanks in advance!
I suggest to catch the string. If string is not "end" then convert to number inside try/catch
you can use this function at the start of your program fflush(stdin). It will clear your input buffer.
You are attempting to read an int and a string in the same line of code. I suggest you use getline() to read the input and try to convert the string to int.
std::string input;
while (heights.size() != 5) {
cout << "Enter a height, or 'end' to quit: ";
if (std::getline(cin, input)) {
if (input == "end") break;
try {
heights.push_back(std::stoi(input));
}
catch (std::invalid_argument e) {
cout << "\nPlease enter an integer: ";
}
}
}
if (string(typeid(height).name()) == "i")
What you had wrong was the comparison of a pointer and string. Since typeid(height).name() returns a pointer to a c-string with the name for the object.

How to Print input value

I have the following bit of code that I'm using to check whether an input is a multiple of 3, 5 or Both. If the user does not enter a number I would like it to print the value stored in UserInput. At the moment it is just returning 0, any suggestions would be much appreciated!
#include <iostream>
using namespace std;
int main()
{
int UserInput;
cout << "Please enter a number:";
cin >> UserInput;
if (!cin) {
cout << UserInput;
}
else if ((UserInput%3 == 0) && (UserInput%5 == 0)) {
cout << "FizzBuzz";
}
else if (UserInput%3 == 0) {
cout << "Fizz";
}
else if (UserInput%5 == 0) {
cout << "Buzz";
}
}
If the user input cannot be read into an int, cin is placed in a fail state and nothing is read. The contents of UserInput are useless to you. You will have to take cin out of the error state with clear and read the stream into something guaranteed to be able to hold the user's input like a std::string.
if (std::cin >> UserInput) // Get input and make sure input was read check for good input
{
// do the fizbuzz thing.
}
else
{
std::cin.clear(); // remove the error flags set by reading a non-number
std::string badinput;
getline(std::cin, badinput); // read the bad input.
std::cout << "User input: " << badinput << std::endl; // write the bad input
}

is sequence necessary between cin.clear() and cin.ignore()?

Let me show you my source at first.
#include <iostream>
#include <limits>
using namespace std;
int main() {
int n;
while (true) {
cout << "Type >> ";
cin >> n;
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Not a number" << endl;
continue;
}
if (n % 2)
cout << "odd";
else
cout << "even";
cout << endl;
}
return 0;
}
Well, This code can run without any problems. however, if I swap between cin.clear() and cin.ignore(), then type character(not integer), it stucks in infinite loop. (consult next code)
#include <iostream>
#include <limits>
using namespace std;
int main() {
int n;
while (true) {
cout << "Type >> ";
cin >> n;
if (cin.fail()) {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
cout << "Not a number" << endl;
continue;
}
if (n % 2)
cout << "odd";
else
cout << "even";
cout << endl;
}
return 0;
}
I wonder sequence is neccesary between cin.clear() and cin.ignore().
if it is, I wanna know why it needs sequence.
Thx for read my Question. I will be very appreciated for any your replies.
sorry for inarticulate Writing.
Let's look at the second snippet step by step:
if (cin.fail()) {
If we enter this, the stream is already bad. So the input operation
cin.ignore(numeric_limits<streamsize>::max(), '\n');
fails immediately and does nothing. Thus, after
cin.clear();
the garbage input is still in the stream and makes
cin >> n;
fail again, without even waiting for input, which gets us back to the beginning.
If you swap the calls around (like in the first snippet), the clear will make the stream "good" again, then ignore successfully gets rid of the garbage input, and the cin >> n; will work as expected.
While cin.fail() is true, any attempts to read from the stream will - eh - fail.
Calling cin.clear() removes the failure flags from the stream, and thus enables input again.

How to forbid the inclusion of non-numbers?

I have this program:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i=0;
float reader, tot = 0;
while(i!=10)
{
cout << "Insert a number: " << endl;
cin >> reader;
if(cin)
{
tot += reader;
i++;
}
else
{
cout << "Error. Please retry." << endl;
cin.clear();
}
}
cout << "Media: " << tot/i << endl;
return 0;
}
In the IF() i want the user to insert ONLY FLOAT VALUES in "reader" variable.
I want that if the user inserts a number, the program continues... else the program should re-ask to the user to insert a correct value.
How to do this checking the INPUT? I tried with a TRY CATCH but it didn't work.
Thanks in advance!
"How to do this checking the INPUT?"
It's already ensured by
cin >> reader;
that only valid float values can be entered by the user. The way to check for validity is
if( cin >> reader ) {
tot += reader;
i++;
}
else {
cout << "Error. Please retry." << endl;
cin.clear();
std::string dummy;
cin >> dummy; // <<< Read invalid stuff up to next delimiter
}
Here's the fully working sample.
"I tried with a TRY CATCH but it didn't work."
To get exceptions from std::istream operations, set the std::istream::exceptions mask.
Just check the result of operator>>:
if (cin >> reader) {
// user gave you a float
tot += reader;
i++;
}
else {
cout << "Error. Please retry." << endl;
// clear the error flag on cin, and skip
// to the next newline.
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Your original program was fine except you need to skip over that bad input when you get an error. Simply clearing the error is not enough:
#include <iostream>
#include <string>
#include <limits> // include this!!!
using namespace std;
int main()
{
int i=0;
float reader, tot = 0.0f; // tot needs to be float
while(i!=10)
{
cout << "Insert a number: " << endl;
if( cin >> reader )
{
tot += reader;
i++;
}
else
{
cout << "Error. Please retry." << endl;
cin.clear();
// Then you ned to skip past the bad input so you
// don't keep tripping the same error
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
cout << "Media: " << tot/i << endl;
return 0;
}
The function cin.ignore() ignores as many input characters as possibly up until the end-of-line character '\n'. The std::numeric_limits<std::streamsize>::max() function tells us the maximum number possible characters that can be stored in an input buffer.
If it is confusing an alternate way to skip the bad input would be to simply read up to the next line into a std::string.
else
{
cout << "Error. Please retry." << endl;
cin.clear();
// Then you need to skip past the bad input so you
// don't keep tripping the same error
std::string skip;
std::getline(cin, skip); // read the bad input into a string
}