c++ why the second input is ignored? - c++

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;
}

Related

after stopping, entering inifinite loop becuase of char data being entered in int data type, The program is printing value which I am unable to figure

Initially, I was trying to write a program to ask the user to enter only a negative integer value and until entered, it will be calling itself in a recursive way. Like:
#include <iostream>
using namespace std;
void printNegativeNum () {
int neg_no;
cout << "Enter a negative number: " << endl;
cin >> neg_no;
if (neg_no >= 0){
cout << "Please enter only negative number." << endl;
printNegativeNum();
}
cout << neg_no;
}
int main(){
printNegativeNum();
return 0;
}
This code on being given char input was entering infinite loop, leading to segmentation fault.
Then, I studied about dealing with this and found few solutions for while loop and tried to do the in above recursive function.
#include <iostream>
using namespace std;
void printNegativeNum () {
int neg_no;
cout << "Enter a negative number: " << endl;
if(cin >> neg_no) {
if (neg_no >= 0){
cout << "Please enter only negative number." << endl;
printNegativeNum();
}
}
cout << neg_no << " ";
}
int main(){
printNegativeNum();
return 0;
}
This thing worked and no more entering the infinite loop. But, now all the previous integer values entered before the char value which leads to program termination, getting printed as if the
court << neg_no << " ";
is getting executed and it was carrying all the values entered before the char constant.
I am unable to understand how?
I in trail and error used cin.clear() before the cout statement. But, that too was in vain.
Please Help.
The problem is that once the second call of the function printNegativeNum returns, the first call of the function printNegativeNum will finish executing, so it too will execute the line cout << neg_no;, which will print garbage.
I don't recommend that you use recursion for solving this problem. Instead, what you want is a loop.
Also, you should test the fail state of the stream, in order to determine whether the input was successfully converted. If the input is found to be invalid, then you should clear the fail state of the stream using cin.clear and should discard the bad input using cin.ignore.
#include <iostream>
#include <limits>
using namespace std;
void printNegativeNum () {
int neg_no;
//the following loop will run forever, until the input is
//found to be valid
while ( true )
{
//prompt user for input
cout << "Enter a negative number: ";
cin >> neg_no;
//determine whether input is valid
if ( !cin.fail() && neg_no < 0 )
break;
//print error message
cout << "Please enter only negative number.\n";
//clear flags on input stream
cin.clear();
//discard bad input
cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
cout << neg_no;
}
int main(){
printNegativeNum();
return 0;
}
This program now has the following behavior:
Enter a negative number: test
Please enter only negative number.
Enter a negative number: 7
Please enter only negative number.
Enter a negative number: -5
-5

Which flag in cin turns to false when you enter a wrong type input [duplicate]

I want to check if the input is valid, but when i do run this code I see that it checks only input for charcters. If i input a float number it will take it and going to use like integer without fractional part.
#inclide <iostream>
using namespace std;
...
int n;
cout << "Your input is: "<<endl;
cin >> n;
while (cin.fail()) {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> n;
}
...
`
So, how to make this code see if the input is float?
You can try to convert the input string to a int using a std::istringstream. If it succeeds then check for eof() (after ignoring blank spaces) to see if the whole input was consumed while converting to int. If the whole input was consumed then it was a valid int.
Something a bit like this:
int input_int()
{
int i;
// get the input
for(std::string line; std::getline(std::cin, line);)
{
// try to convert the input to an int
// if at eof() all of the input was converted - must be an int
if(!line.empty() && (std::istringstream(line) >> i >> std::ws).eof())
break;
// try again
std::cout << "Not an integer please try again: " << std::flush;
}
return i;
}
int main()
{
std::cout << "Enter an integer: " << std::flush;
std::cout << "i: " << input_int() << '\n';
}
Building on Raindrop7's solution, here's the full code to do what you need:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double m;
cout << "Your input is: "<<endl;
cin >> m;
while (cin.fail() || (m-floor(m)))
{
cout << "Error. Nubmer of elements has to be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> m;
}
int n = (int)m;
return 0;
}
Here's a sample output:
Your input is:
2.7
Error. Nubmer of elements has to be integer. Try again:
erer
Error. Nubmer of elements has to be integer. Try again:
2
The code below should be able to do what you are hoping to achieve:
#inclide <iostream>
using namespace std;
int n;
cout << "Your input is: "<<endl;
while (!(cin >> n) || cin.get() != '\n') {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
}
The program asks the user to re-enter an integer if either of the following happens:
If the program is unable to extract an integer from the std::cin stream. (For example, when a character or string is entered by the user)
If, after an integer is extracted successfully, the next character in std::cin is not the new line '\n' character. (For example, when a number with a decimal point like 1.1 is entered, or when an integer followed by a character like 1a is entered.)

loop repeats without prompting the user again?

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;
}

CIN within certain range

I am trying to make a cin where the user can only enter 0 to 1. If the user doesnt enter those numbers then he should get an error saying "Please enter within the range of 0 to 1."
But its not working.
What am i doing wrong?
int alphaval = -1;
do
{
std::cout << "Enter Alpha between [0, 1]: ";
while (!(std::cin >> alphaval)) // while the input is invalid
{
std::cin.clear(); // clear the fail bit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the invalid entry
std::cout << "Invalid Entry! Please Enter a valid value: ";
}
}
while (0 > alphaval || 1 < alphaval);
Alpha = alphaval;
Try this:
int alphaval;
cout << "Enter a number between 0 and 1: ";
cin >> alphaval;
while (alphaval < 0 || alphaval > 1)
{
cout << "Invalid entry! Please enter a valid value: ";
cin >> alphaval;
}
If you want to trap empty lines I'd use std::getline and then parse the string to see if the input is valid.
Something like this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int alphaval = -1;
for(;;)
{
std::cout << "Enter Alpha between [0, 1]: ";
std::string line;
std::getline(std::cin, line);
if(!line.empty())
{
std::stringstream s(line);
//If an int was parsed, the stream is now empty, and it fits the range break out of the loop.
if(s >> alphaval && s.eof() && (alphaval >= 0 && alphaval <= 1))
{
break;
}
}
std::cout << "Invalid Entry!\n";
}
std::cout << "Alpha = " << alphaval << "\n";
return 0;
}
If you want a different prompt on error then I'd put the initial prompt outside the loop and change the inner prompt to what you prefer.
Week one of C++, starting with Peggy Fisher's Learning C++ on Lynda.com.
This is what I came up with. Love to receive feedback.
int GetIntFromRange(int lower, int upper){
//variable that we'll assign input to
int input;
//clear any previous inputs so that we don't take anything from previous lines
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//First error catch. If it's not an integer, don't even let it get to bounds control
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
//Bounds control
while(input < lower || input > upper) {
cout << "Out of Range. Re-enter option: ";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//Second error catch. If out of range integer was entered, and then a non-integer this second one shall catch it
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
//return the cin input
return input;
}
As the exercise was to order Hamburgers, this is how I ask for the amount:
int main(){
amount=GetIntFromRange(0,20);
}

How Can I avoid char input for an int variable?

The program below shows a 'int' value being entered and being output at the same time. However, when I entered a character, it goes into an infinite loop displaying the previous 'int' value entered. How can I avoid a character being entered?
#include<iostream>
using namespace std;
int main(){
int n;
while(n!=0){
cin>>n;
cout<<n<<endl;
}
return 0;
}
Reason for Infinite loop:
cin goes into a failed state and that makes it ignore further calls to it, till the error flag and buffer are reset.
cin.clear();
cin.ignore(100, '\n'); //100 --> asks cin to discard 100 characters from the input stream.
Check if input is numeric:
In your code, even a non-int type gets cast to int anyway. There is no way to check if input is numeric, without taking input into a char array, and calling the isdigit() function on each digit.
The function isdigit() can be used to tell digits and alphabets apart. This function is present in the <cctype> header.
An is_int() function would look like this.
for(int i=0; char[i]!='\0';i++){
if(!isdigit(str[i]))
return false;
}
return true;
If you want use user define function you can use the ascii/ansi value to restrict the char input.
48 -57 is the range of the 0 to 9 values
#include <iostream>
#include <climits> // for INT_MAX limits
using namespace std;
int main()
{
int num;
cout << "Enter a number.\n";
cin >> num;
// input validation
while (cin.fail())
{
cin.clear(); // clear input buffer to restore cin to a usable state
cin.ignore(INT_MAX, '\n'); // ignore last input
cout << "You can only enter numbers.\n";
cout << "Enter a number.\n";
cin >> num;
}
}
You need to check for cin fail
And
You need clear the input stream
See the following example.
It is tested in recent compilers
#include <iostream>
using namespace std;
void ignoreLine()
{
cin.clear();
cin.ignore();
}
int main(int argc, char const* argv[])
{
int num;
cout << "please enter a integer" << endl;
cin >> num;
while (cin.fail()) {
ignoreLine();
cout << "please enter a integer" << endl;
cin >> num;
}
cout << "entered num is - " << num << endl;
return 0;
}