Character left on the input stream causing infinite loop [duplicate] - c++

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}

Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.

Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}

Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)

Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Related

How to validate integer input vs character input [duplicate]

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.
Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)
Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Terminating a While loop when getting numbers [duplicate]

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.
Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)
Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

why is this function not taking input after second recursion? [duplicate]

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.
Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)
Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

C++ infinite loop on wrong input [duplicate]

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.
Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)
Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

about asking the user to input again when invalid input occurs [c++] [duplicate]

In the following loop, if we type characters as the cin input instead of numbers which are expected, then it goes into infinite loop. Could anyone please explain to me why this occurs?
When we use cin, if the input is not a number, then are there ways to detect this to avoid abovementioned problems?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Well you always will have an infinite loop, but I know what you really want to know is why cin doesn't keep prompting for input on each loop iteration causing your infinite loop to freerun.
The reason is because cin fails in the situation you describe and won't read any more input into those variables. By giving cin bad input, cin gets in the fail state and stops prompting the command line for input causing the loop to free run.
For simple validation, you can try to use cin to validate your inputs by checking whether cin is in the fail state. When fail occurs clear the fail state and force the stream to throw away the bad input. This returns cin to normal operation so you can prompt for more input.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
For more sophisticated validation, you may wish to read into a string first and do more sophisticated checks on the string to make sure it matches what you expect.
Attention
Please pay attention to the following solution. It is not complete yet to clear the error in your case. You will still get an infinite loop!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Complete Solution
The reason is you need clear the failed state of stream, as well as discard unprocessed characters. Otherwise, the bad character is still there and you still get infinite loops.
You can simply can std::cin.ignore() to achieve this. For example,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Another Solution
You can also use getline and stringstream to achieve. Here is a brief example.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Perhaps, it's because,
cin is a streaming function. When a
non-numeric is entered instead of
numbers, it is ignored. And you are
prompted for re-entry.
Even if you did give numeric inputs,
you will be prompted for more inputs since you're on an infinite loop.
You can solve this problem like this:
1. Create a function to take in a string input.
2. return it as numeric after conversion. Use strtod() for conversion.
Hope this helps :)
Another alternative is operator! ,it is equivalent to member function fail()
//from Doug's answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric's answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}