Cin.Ignore() is not working - c++

Here I have a code:
cout << "Press Enter To Exit...";
cin.ignore();
this program will execute and will wait till you press enter and then it will exit.
now see this code:
int m;
cin >> m;
cout << "Press Enter To Exit...";
cin.ignore();
this time after entering a number for saving in "m" the program will exit without waiting for cin.ignore command which waits for pressing enter.
I mean if you use cin command before cin.ignore, the cin.ignore command will skip. why? and what should I do for fixing it?

cin.ignore() basically clears any input left in memory. In the first piece of code, you did not input anything, hence it will have nothing to clear and because of that it waits for you to input something.
In the second piece of code you used the >> operator which gets formated input but leaves the end line character '\n' (the one that gets stored when you press ENTER) wandering in the input buffer. When you call cin.ignore() it then does it job and clears that same buffer.As it already did what he was called to it simply lets the program continue (in this case to the end). Remember cin.ignore() is for clearing the input buffer(small piece of memory that holds the input) if you want the user to input something before the program moves on use cin.get().
You should also know this:
If using:
->cin<< you should call cin.ignore() afterwards because it does not consume the end line character '\n' which will be consumed next time you ask for input causing unwanted results
such as the program not waiting for you to input anything.
->cin.get() you should not call cin.ignore() because it consumes the '\n'
->getline(cin,yourstring) (gets a whole input line including the end line character) you should also not use cin.ignore()

Use
int m;
cin >> m;
cin.ignore();
cout << "Press Enter To Exit...";
cin.ignore();

Use this.
std::cin.sync(); std::cin.get();

when you use cin >> m you type value of m and then press enter, the enter '\n' goes into buffer and cin.ignore(); ignores it and program ends.

Related

C++ cin.ignore() skip loop

I created a for loop in my program that makes it so you have to press enter to continue. I did this Using cin.ignore().
This is the basic idea of the code that I am using.
for (int i = 0; i < 5; i++) { // loop will do it for each player data
cout << "Press Enter to Continue ";
cin.ignore();
system("cls");
cout << "Playes Data" << endl;
}
This code works fine until the player decides to input something rather than just press enter.
From what I understand, because the player inputted something, this means that there will be a buffer. You can get rid of the buffer from just using cin.ignore. This makes it so it skips an iteration and the player doesn't have to press enter to continue. I have just included a second cin.ignore, but I don't want them to have to press enter twice. Is there some way to use the second cin.ignore only if there is a buffer, or is there some other way to deal with this?
There is always a buffer. Calling std::cin.ignore() by itself, with no parameter values, simply skips the next char in the buffer, which may or may not be a '\n' char from an ENTER press.
To skip everything in the buffer, up to the next ENTER press, use std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n').
You can replace
cin.ignore();
with
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Where the second option will ignore all characters including the newline the enter key puts into the stream.

Avoid bad user input (string when what's asked is an integer)

I have an infinite while loop, where the user is asked for a number.
My problem is very simple: If the input is a string, I want to re-ask user for input, outputting the message "Enter a valid choice: ".
I searched, and looks like I should check for cin.fail(), then call cin.clear() and cin.ignore().
Here's my code:
int main() {
int choice;
bool failed = false;
while (true) {
if (failed) cout << "Enter a valid choice: ";
else cout << "Enter a number: ";
cin >> choice;
if (cin.fail()) {
cin.clear();
cin.ignore();
failed = true;
}
}
return 0;
}
However, this doesn't really fix my problem. Of course, it isn't printing infinitely, but for each letter extra letter , it prints another "Enter a valid choice:"
Seems like I need to call cin.ignore() for each extra letter.
Any other way of doing this?
You have an infinite loop because you are not breaking the loop even when valid input is enter. Is that what you really want? If so, at the least, you are not resetting the failed flag in valid input.
More importantly, when invalid input is entered, you are not ignoring everything that was enteted, you are only ignoring 1 char at a time. That is why you see extra prompts.
Try this instead :
int main() {
int choice;
while (true) {
cout << "Enter a number: ";
while (!(cin >> choice)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter a valid choice: ";
}
}
return 0;
}
The reason it is printing so many times is because you are only clearing the state of cin, but aren't clearing the input buffer. You can do so in multiple ways:-
Use fflush(stdin) to clear the input buffer.This is the C method and can be done by including cstdio header.
Use the cin.ignore to ignore all characters in the current input stream. You can do this by replacing the line cin.ignore() which ignores a single character by this code cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') which ignores the entire line. For this you need the limits header.
Finally you can do the same with a simple loop like while (cin.get() != '\n'){continue;} which ignores all characters till new line.
Also another approach to the same problem is to take the input in form of a string and use the strtol() or the isdigit() functions to check if the input is valid.
By the way the infinite loop is because you have not used the break statement to terminate the loop. So you can avoid this by adding
if(!failed)
break;
Also you need to change the state of Failed at the entry of each loop by adding
failed=false;
at the start of the loop body.

cin.get(); doesn't work when I put it in a if statement

I used cin.get() to get the program to pause and wait for user input, and it works fine. The moment I put it in an if statement, it just skips that "wait" period and continues on with the code? How can I solve this. Here is the section that is not working.
do
{
cout << "\n\n\nEnter the number of one of the following and I will explain!\n";
cout << "1.integer 2.boolian 3.floats 4.doubles 5.character";
cout << "\n\n[when you are done type 'done' to continue]\n\n";
cin >> option;
if (option = 1);
{
cout << "\nInteger is the variable abbreviated as 'int' this allows C++ to only";
cout << "\nreadwhole and real numbers \n\n";
cin.get(); //this is the part where it just skips.. it should wait
}
} while (var = 1);
The problem is that cin >> option will extract whatever integer is in the input stream but will leave the following newline character (which is there from hitting enter after typing in the value). When you do cin.get() it is simply extracting that newline character which is already there. Like so many other questions like this, the solution is to empty the input stream after you've extracted into option:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
You are also using assignment (=) where you should be comparing for equality (==).

cin condition checking error

I am a beginner programmer learning c++. I am having a nagging issue with the cin command.
In the program section below, if I enter a wrong type at the 1st cin command, the program will not execute any of the following cin commands at all, but will execute the rest of the program.
//start
#include <iostream>
using namespace std;
int main()
{
int x=0;
cout << endl << "Enter an integer" << endl;
//enter integer here. If wrong type is entered, goes to else
if (cin >> x){
cout << "The value is " << x << endl;
}
else {
cout << "You made a mistake" << endl; //executes
cin.ignore();
cin.clear();
}
cout << "Check 1" << endl; //executes
cin >> x; //skips
cout << "Check 2" << endl; //executes
cin >> x; //skips
return 0;
}
//end
Instead of the if else, if i put the same concept in a loop
while (!(cin >> x))
the program goes into an infinite loop upon enterring a wrong input.
Please help me explain this phenomenon, as the text book i am following says the code typed above should work as intended.
Thank you
cin is an input stream. If an error occurs cin goes into a let's call it "error occured" state. While in this state no character input can be made, your request to collect a character from the input stream will be ignored. With clear() you clear the error and the input stream stops ignoring you.
Here is the ignore function prototype
istream& ignore ( streamsize n = 1, int delim = EOF );
This function gets characters from the input stream and discards them, but you can't get any character if your stream is ignoring you, so you have to first clear() the stream then ignore() it.
Also, a note on the side: If someone inputs, for example "abc", on the first input request your cin gets only one character that is 'a' and "bc" stays in the buffer waiting to be picked up, but the next call to cin gets the 'b' and 'c' stays in the buffer, so you again end up with an error.
The problem with this example is that the cin.ignore() if no arguments are handed to it only ignores 1 character after you clear(). and the second cin gets 'c' so you still have a problem.
A general solution to this problem would be to call
cin.ignore(10000, '\n');
The first number just has to be some huge number that you don't expect someone would enter, I usually put in 10000.
This call makes sure that you pick up all the characters from the false input or that you pick up every character before the enter was pressed so your input stream doesn't get into the "error occurred" state twice.
You may also want to try
if ( std::cin.fail() )
as a backup to prevent a crash due to input of the wrong type when prompted

Using cin.get() in a tight loop

I'm not new to programming, but I am relatively new to C++. I would like to distribute simple console applications so I can help others as I learn. The vast majority of machines on the campus of my university are windows based, and have the Borland compiler installed by default. I prefer to do my development on a Linux-based system with g++ and other tools. So I'd like to add some cross-platform way of leaving the program running until the user presses enter. That way, the user is able to view the output even if he or she double clicked on the exe rather than running it in the console in windows. To do this, I wrote something similar to:
#include <iostream>
using namespace std;
int main()
{
float val1, val2;
bool wait = true;
cout << "Please enter the first value to add: ";
cin >> val1;
cout << "Please enter the second value to add: ";
cin >> val2;
cout << "Result: " << val1 + val2 << endl << endl;
cout << "Press enter to exit...";
while (wait)
{
if (cin.get() == '\n')
wait = false;
}
return 0;
}
Using the code above, the program exits after displaying the result. However, if you comment out the cin calls, it works as expected. This leads me to believe that cin.getline is picking up my enter key press from my last data entry. I suspect this is due to the tightness of the loop. I have learned that there is no cross-platform sleep function in C++, so that is not an option. What else can I do to make this work?
You can add
cin.ignore(1);
or
cin.ignore(INT_MAX, '\n');
before you call cin.get(). This will ignore the newline left from the user entering the second number or all the characters in the buffer until a newline.
Also you neither need to compare the return value of get to '\n' nor put it in a loop. The user has to hit enter for get to return, so
cout << "Press enter to exit...";
cin.ignore(INT_MAX, '\n');
cin.get();
Is sufficient.
What happens if you do
cout << "Press enter to exit...";
while (wait)
{
if (cin.get() == '\n')
wait = false;
}
Is that the loop is entered, and cin.get() is called. The user can enter any amount of text at the console as he wants. Say they entered
Hello
in the console. Then the user presses the Enter key. cin.get() returns H, and ello\n is still left in the buffer. You compare H with \n and see that they are not equal, continue the loop. cin.get() is called and since there is already text in the buffer, returns e immediately. This loop continues wasting time until it gets to the last character of the buffer which is \n and it compares true with \n so the loop breaks. As you can see, this is a waste of time.
If you do put cin.get() in a loop and compare the return value of it with \n, there is also the danger of cin coming to an end-of-file before an \n is encountered. I believe the effect of this on your program would be an infinite loop, but I'm not sure since I can't try it on Windows.
Also, even though you don't need to use a loop in the first place, you are wasting even more time with a bool because you could reduce the loop to
while (true)
if (cin.get() == '\n') break;
After cin >> you should ignore all the characters in the buffer until the `\n' with
#include <limits> // for std::numeric_limits as indicated by Marlon
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
Then you can wait for the next line with:
cout << "Press enter to exit...";
cin.get();