Code stuck looping while when numeric value entered - c++

Hey my code is stuck on looping my while when I input numeric letters, it just floods my output with "Invalid Input, please try again." It's just a simple menu.

If you ever enter anything "invalid", such that reading from cin will cause an error, you have to call cin.clear() to be able to read further input, otherwise the stream in operator will just return immediately.
Typically, when reading user input, you check the state of cin and exit or do some error handling when it is invalid. In addition, on a failed input attempt, the characters that caused the error will still be sitting in cin, and need to be ignored (e.g., up to the next newline):
#include <iostream>
#include <limits>
int main() {
int userOption;
while(1) {
while(!(std::cin >> userOption)) {
std::cout << "Invalid input." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << userOption << std::endl;
}
return 0;
}

The problem is with the following line of code,
cin.ignore(numeric_limits<streamsize>::max(), '\n');
When you are entering a single number, you don't have to ignore any other character. So simply remove the above line of code to correct your program.

Related

Cin not waiting for input despite cin.ignore()

I'm new to C++ and I'm using Visual Studio 2015.
cin is not waiting for input after "Please enter another integer:\n" and outputs "You entered 0" every time.
I've searched the Internet more than an hour without a solution. No combination of cin.ignore() is working. Why is the cin buffer still not cleared?
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vals;
int val = 0;
int n = 0;
cout << "Please enter some integers (press a non-numerical key to stop)\n";
while (cin >> val)
vals.push_back(val);
cin.ignore(INT_MAX, '\n');
cin.ignore();
cout << "Please enter another integer:\n";
cin.ignore();
cin >> n;
cout << "You entered " << n;
system("pause");
return 0;
}
The problem is for the user to exit the loop you need to put the cin in a failed state. That is why your
while(cin >> val){ .... }
is working.
If in a failed state cin is no longer in a position to supply you with input so you need to clear() the failed state. You also need to ignore() the previously non-integer response that triggered the failed state initially.
It would also be of merit to use
if(cin >> n){
cout << "You entered " << n;
}
This will assert that a proper input for n was provided.
The problem in your program is that it expects integers, whereas a user can input anything, like a non-integer char.
A better way to do what you seem to want to do is to read characters one by one, ignoring whitespace, and if it's a digit, then continue reading to get the whole number, else stop the loop. Then you can read all chars until you reach '\n', and do the same for one number. While you do that, for each character you should check that there can still be characters in the stream with cin.eof().
Also, instead of using system("pause"), you can prevent the command line window from closing by requesting a last character before terminating the application.
Try getting your integers like this :
#include <sstream>
...
fflush(stdin);
int myNum;
string userInput = "";
getline(cin, userInput);
stringstream s (userInput);
if (s >> myNum) // try to convert the input to int (if there is any int)
vals.push_back(myNum);
without sstream you have to use try catch, so your programme won't crash when input is not an integer

Cin Not Working in While Loop [duplicate]

Here Im trying to get an integer from user, looping while the input is correct.
After entering non integer value (e.g "dsdfgsdg") cin.fail() returns true, as expected and while loop body starts executing.
Here I reset error flags of cin, using cin.clear(); and cin.fail() returns false, as expected.
But next call to cin doesn't work and sets error flags back on.
Any ideas?
#include<iostream>
using namespace std;
int main() {
int a;
cin >> a;
while (cin.fail()) {
cout << "Incorrect data. Enter new integer:\n";
cin.clear();
cin >> a;
}
}
After cin.clear(), you do this:
#include <iostream> //std::streamsize, std::cin
#include <limits> //std::numeric_limits
....
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
What the above does is that it clears the input stream of any characters that are still left there. Otherwise cin will continue trying to read the same characters and failing
As a matter of style, prefer this method:
int main()
{
int a;
while (!(std::cin >> a))
{
std::cout << "Incorrect data. Enter new integer:" << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
cin.clear() does not clear the buffer; it resets the error flags. So you will still have the sting you entered in your buffer and the code will not allow you to enter new data until you clear the cin buffer. cin.Ignore() should do the trick
There is also a very easy method:
#include <iostream>
std::cin.clear() //reset stream state so that cin.fail() becomes false.
std::cin.ignore(INT_MAX,'\n'); //clear the stream from any remaining characters until the \n which is present at the end of any cin.
This will reset stream state and clear any remaining things in it. Much easier, less code, and less header files.

Why does this code give me an infinite loop?

When I enter in a correct value (an integer) it is good. But when I enter in a character, I get an infinite loop. I've looked at every side of this code and could not find a problem with it. Why is this happening? I'm using g++ 4.7 on Windows.
#include <iostream>
#include <limits>
int main()
{
int n;
while (!(std::cin >> n))
{
std::cout << "Please try again.\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
}
}
Input: x
Output:
It's because your recover operations are in the wrong order. First clear the error then clear the buffer.
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
You have to clear the error state first, and then ignore the unparsable buffer content. Otherwise, ignore will do nothing on a stream that's not in a good state.
You will separately need to deal with reaching the end of the stream.

Why does the program end when I enter a number?

I began programming on C++ some days ago and something is really getting me troubles:
whenever I enter the number, the program ends.
Code:
using namespace std;
int main()
{
int entry;
cout << "Write a number: ";
cin >> entry;
cout << entry;
cin.get();
return 0;
}
I need some help here so my programs could run right.
By right I mean to output the number after ending... but it just ends after I enter the number and press enter It does not print it.
UPDATE:
For the sake of the ones who didn't understood what I was meaning (sorry for my english)
Ok let me explain.
-So the program is suposed to get the values from the keyboard right.
-I enter a number let´s say is 6, ok now I press enter.
-Alright now the number is supposed to be output on the screen, but this doesn´t happen because the program closes too fast.
But this was solved actually, by adding a second cin.get(); or by adding a cin.ignore(); after each data input petition.
Here's a slightly improved version that might be closer to what you wanted:
#include <string>
#include <sstream>
#include <iostream>
int main()
{
int n;
std::string line;
while (true)
{
std::cout << "Please enter an integer: ";
if (!(std::getline(std::cin, line))) { return 1; /* error! */ }
std::istringstream iss(line);
if (iss >> n) { break; }
}
std::cout << "Thank you. You said: " << n
<< "\n\nPlease press Enter to quit.";
std::getline(std::cin, line);
}
The error condition in the getline is triggered when the input stream is closed or otherwise terminated before another line could be read (e.g. if you hit Ctrl-D on the console). The token extraction into n fails until you enter a valid integer, and the loop will continue looping until this happens.
All you need to do is consume the newline that is left over after reading the integer.
This happens in java as well.
using namespace std;
int main()
{
int entry;
cout << "Write a number: ";
cin >> entry;
cout << entry;
cin.get(); //Consume newline
cin.get();
return 0;
}
get() reads one and only one character from the stream, so it's perfectly normal that the program ends after you enter your number.
Have a look either at the std::basic_istream<>::getline() method or, easier, std::getline() which doesn't require a dynamic buffer.
If you need more information about basic IO in C++, you can read the following documentation : Basic Input/Output - C++
Update
Like stated in the comments, I missunderstood the question, I was initially thinking that only one digit was read into the variable.
After reading carefully again, I'm unable to understand what the problem is.
The reason for this is youre using
cin.get();
return 0;
at the end of the program , the cin.get() reads the number you entered then goes straight to return 0; thus ending the program.
to stop this you can add an extra cin.get(); before return 0;
or use
system("Pause");
before return 0; instead

Infinite loop on EOF in C++

This code works as desired for the most part, which is to prompt the user for a single character, perform the associated action, prompt the user to press return, and repeat. However, when I enter ^D (EOF) at the prompt, an infinite loop occurs. I am clearing the error state via std::cin.clear() and calling std::cin.ignore(...) to clear the buffer. What could be causing the infinite loop?
#include <iostream>
#include <limits>
void wait()
{
std::cout << std::endl << "press enter to continue.";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
std::cin.get();
}
int main()
{
char response;
while (true)
{
std::cout << "enter a character at the prompt." << std::endl << "> ";
std::cin >> response;
switch (response)
{
case 'q':
exit(0);
break;
}
wait();
}
}
I am running this in the Mac OS X terminal, if it matters.
UPDATE: What I am really asking here is, when the user enters EOF (^D) at the prompt, how do I (a) detect it and (b) reset the stream so that the user can continue to enter data.
The following example is different from the code above, but illustrates the same principle of clearing the stream after a ^D has been detected and continuing to read from that stream.
> a
you entered: a
> b
you entered: b
> ^D
you entered EOF
> c
you entered: c
...
You should always check whether any of a stream's failure flags are set after calling formatted extraction operation, in your example you are checking response without checking whether response was correctly extracted.
Also, you are using std::endl in your prompt output where it doesn't make sense. std::endl prints \n and then flushes the buffer, but you then immediately print more characters so the flush is redundant. As cin and cout are (usually) tied, calling an input function for std::cin will cause std::cout to be flushed in any case so you may as well put a \n into your prompt string and save on the verbose extra << operators.
Why not make a prompting function that prints the prompt, retrieves the input an returns a reference to the stream so that you can test it for success using the usual stream to boolean type conversion.
This way you can get rid of the while true and explicit break.
std::istream& prompt_for_input( std::istream& in, std::ostream& out, char& response )
{
out << "enter a character at the prompt.\n> ";
in >> response;
return in;
}
int main()
{
char response;
while ( prompt_for_input( std::cin, std::cout, response ) && response != 'q' )
{
wait();
}
}
The question does not really make sense for standard input. It will be hard to read something from standard input after that stream has ended -- you'll have to re-open it somehow, but there is no way to re-open standard input. It might be connected to a pipe, or to a file, or to a terminal -- and there's no behaviour suitable for all of these.
So you're going to be reading explicitly from the terminal, I assume. On UN*X systems, that means reading /dev/tty, and re-opening it when needed. Here's a simple example that does it; most error-checking omitted.
// Warning: UN*X-specific
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
for(unsigned i=0; ; i++) {
ifstream tty("/dev/tty");
if (! tty) {
cerr << "Failed to open TTY" << endl;
return 2;
}
string s;
while (getline(tty,s))
cout << i << ": " << s << endl;
}
return 0; // (unreached)
}
You'll need to clear the flags to get the stream to do much of anything after it encounters EOF.
Err, I may be missing something, but I don't ever see you break out of the while (true) loop.
// ...
while (true) {
if (std::cin.eof()) {
break;
}
// ...
}
Upon reading an EOF, you just ignore it and loop back, without exiting the loop, so you'll continually read the EOF and continually loop. If you want to do something on seeing an EOF, you need to handle it either in your switch or before.
Perhaps you want to read input from somewhere after the user has closed your stdin with ^D? In that case, you'll have to close cin and reopen it to read from the other place you want to read input from.
As mentioned, you need to make sure the stream is not in a bad state. I would change while condition to use good(). Don't just check EOF as there are several ways a stream can become "bad" other than EOF.
while (std::cin.good()) {...
while ((std::cout << "Enter a character at the prompt ")
&& (!(std::cin >> response) || response =='q')) {
std::cout << "Not a valid input";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}