Hi, first post :cheesy:

I'm currently a complete noob to c++ programming and am currently reading the book "Beginning C++ Game Programming" written by Michael Dawson. I had the problem where i complied and ran the following source code:

#include <iostream>
 
int main()
 
{
std::cout << "Game Over!";
std::cin.ignore(std::cin.rdbuf()->in_avail() + 1);
return 0;
}

This would pop up with a window and it would then very quickly dissapear, in the book it says that this might happen and says to use the following code just before the

return 0;

bit:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 1 )

This then ofcourse worked and i have to press enter to close the window that pops up (you'll see why i have written this later).

I then moved a tiny bit further into the book and used the following code:

#include <iostream>
 
using namespace std;
 
int main()
{
int score; 
double distance; 
char playAgain; 
short lives, aliensKilled;
 
score = 0;
distance = 1200.76;
playAgain = 'y';
lives = 3;
aliensKilled = 10;
 
double engineTemp = 6572.89;
cout << "\nscore: " << score << endl;
cout << "distance: " << distance << endl;
cout << "playAgain: " << playAgain << endl;
cout << "lives: " << lives << endl;
cout << "aliensKilled: "<< aliensKilled << endl;
cout << "engineTemp: " << engineTemp << endl;
 
int fuel;
cout << "\nHow much fuel? ";
cin >> fuel;
cout << "fuel: " << fuel << endl;
 
typedef unsigned short int ushort;
ushort bonus = 10;
cout << "\nbonus: " << bonus << endl;
return 0;
}

The problem with this one is that at the red highlighted bit the user is meant to input a number into the window and press enter. I have read on this forum that you can use the following code to get around the problem:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 2 )

Lo and behold it works aswell.

Now onto the real question :rolleyes:

The two following bits of source:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 1 )
std::cin.ignore(std::cin.rdbuf()->in_avail() + 2 )

I have no idea what the things in them are for and how the hell it is solving the problem for me, as i have read (again on this forum) it isn't exactly good practice to wack in code and just remember not to mess up again in the future. So i was therefore wandering if you lot could tell me what the things in this mean and do so that they solve the problem so that i can use the code with actually knowing what it is doing. Considering I'm a complete noob and won't understand any real techincal jargon yet (read the book for about 3 hours now and only 20 pages in :lol: ) can you explain it in a way that even George Bush could understand. Cheers :cheesy:

IDE = Dev-C++ LINKY

Recommended Answers

All 13 Replies

It's a convoluted way of clearing the input buffer of characters left after the previous read. When you read a number using cin , the characters after the number are left in the buffer for the nect cin to read. That basically means the ENTER is still there, and when you attempt to read a string, the first thing it sees is ENTER, so it's happy. That convoluted cin.ignore() clears the buffer.

It's a bandaid that's necessary because cin is a relatively misbehaved command. It's ultimately better to read a full line using getline() and then parse the line into it's components.

Hi, first post :cheesy:

I'm currently a complete noob to c++ programming and am currently reading the book "Beginning C++ Game Programming" written by Michael Dawson. I had the problem where i complied and ran the following source code:

#include <iostream>
 
int main()
 
{
std::cout << "Game Over!";
std::cin.ignore(std::cin.rdbuf()->in_avail() + 1);
return 0;
}

This would pop up with a window and it would then very quickly dissapear, in the book it says that this might happen and says to use the following code just before the

return 0;

bit:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 1 )

This then ofcourse worked and i have to press enter to close the window that pops up (you'll see why i have written this later).

I then moved a tiny bit further into the book and used the following code:

#include <iostream>
 
using namespace std;
 
int main()
{
int score; 
double distance; 
char playAgain; 
short lives, aliensKilled;
 
score = 0;
distance = 1200.76;
playAgain = 'y';
lives = 3;
aliensKilled = 10;
 
double engineTemp = 6572.89;
cout << "\nscore: " << score << endl;
cout << "distance: " << distance << endl;
cout << "playAgain: " << playAgain << endl;
cout << "lives: " << lives << endl;
cout << "aliensKilled: "<< aliensKilled << endl;
cout << "engineTemp: " << engineTemp << endl;
 
int fuel;
cout << "\nHow much fuel? ";
cin >> fuel;
cout << "fuel: " << fuel << endl;
 
typedef unsigned short int ushort;
ushort bonus = 10;
cout << "\nbonus: " << bonus << endl;
return 0;
}

The problem with this one is that at the red highlighted bit the user is meant to input a number into the window and press enter. I have read on this forum that you can use the following code to get around the problem:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 2 )

Lo and behold it works aswell.

Now onto the real question :rolleyes:

The two following bits of source:

std::cin.ignore(std::cin.rdbuf()->in_avail() + 1 )
std::cin.ignore(std::cin.rdbuf()->in_avail() + 2 )

I have no idea what the things in them are for and how the hell it is solving the problem for me, as i have read (again on this forum) it isn't exactly good practice to wack in code and just remember not to mess up again in the future. So i was therefore wandering if you lot could tell me what the things in this mean and do so that they solve the problem so that i can use the code with actually knowing what it is doing. Considering I'm a complete noob and won't understand any real techincal jargon yet (read the book for about 3 hours now and only 20 pages in :lol: ) can you explain it in a way that even George Bush could understand. Cheers :cheesy:

IDE = Dev-C++ LINKY

The "std::" portion of a given statement says to the compiler, "The following calls (i.e cin.ignore(...)) will be called with the definitions defined under the "std" namespace. If you include two files containing two different classes, perhaps used for two different purposes, and it contains class names that are the same, how is the compiler suppose to know what call is to what class? Namespace solve this problem by having libraries declared under a unique namespace. In effect, two libraries can contain classes with the same name, as long as they're under different namespaces, basically.

Also, you don't have to use the "std::" all the time to indicate a particular namespace, you could simply insert this:

using namespace std;

after your "#includes ..." then you could just delete all statements preceeding "std::".

Good luck, LamaBot

yes i just do

using namespace std

then im like

cout << "Hello";
cin >> variablex;

yes i just do

using namespace std

then im like

cout << "Hello";
cin >> variablex;

Then you haven't run into the scoping issues associated with that yet. ;)

yes i just do

using namespace std

then im like

cout << "Hello";
cin >> variablex;

Waltp is right, however, I'm going to try to give a more thourough explaination.

Just think of cin as a way to access a buffer that holds characters until it reaches an ENTER character. The buffer can also hold the ENTER character. As Waltp indicated, the cin buffer sometimes retains an ENTER character because if misbehaviour. So, next time you call "cin >> variable", it will reach the left over ENTER chacter and continue, not allowing any input from the user. There is a read position in the buffer, which indicates a relative reading point. The "rdbuf->in_avail()" member function simply returns the number of characters in the current buffer, excluding the ENTER character. The "ignore" member function uses a number ( the parameter ), which relocates the read position of the input buffer that many number of positions. Now the statement "cin.ignore(cin.rdbuf->in_avail + 1) says, "Place the read position to the end of the input buffer, plus 1 position passing the ENTER character. On the next call to "cin >> variable", it'll start be read for a new input and won't just prompt then continue because of the left over ENTER character.

Good luck, LamaBot

>So, next time you call "cin >> variable", it will reach the left over ENTER chacter and continue, not allowing any input.
Not quite. cin actually keeps searching/waiting until it finds data. This behaviour is fine until you start using getline() [edit] or until the user types in more data than one variable [/edit], which simply stops when it finds a newline character. That is why the input buffer must be flushed when mixing cin >> and getline .

? simple terms please :)

? simple terms please :)

Consider this simple program:

#include <iostream>
#include <string>

int main() {
    
    std::string firstName;
    std::string lastName;
    std::cout << "Please enter your first and last name" << std::endl;
    std::cin >> firstName >> lastName;
    std::cout << "Hello " << lastName << ", " << firstName << std::endl;
    
    return 0;
}

My output:

Please enter your first and last name
Joe




Programmer
Hello Programmer, Joe

Notice all the extra returns I hit? cin kept waiting for data, and until then it refused to print the last line.

By contrast, consider this modification:

#include <iostream>
#include <string>

int main() {
    
    std::string firstName;
    std::string lastName;
    std::cout << "Please enter your first name" << std::endl;
    std::cin >> firstName;
    std::cout << "Please enter your last name" << std::endl;
    std::cin >> lastName;
    std::cout << "Hello " << lastName << ", " << firstName << std::endl;
    
    return 0;
}

My output:

Please enter your first name
Joe Programmer
Please enter your last name
Hello Programmer, Joe

Notice how the second line was skipped completely? The first input, cin searched for data, and got "Joe". It stopped, because that's all that was needed, leaving "Programmer" in the buffer.

The second cin picked this up and continued, never giving me the chance to enter some input in the second cin statement.

>So, next time you call "cin >> variable", it will reach the left over ENTER chacter and continue, not allowing any input.
Not quite. cin actually keeps searching/waiting until it finds data. This behaviour is fine until you start using getline() [edit] or until the user types in more data than one variable [/edit], which simply stops when it finds a newline character. That is why the input buffer must be flushed when mixing cin >> and getline .

Yeah, I didn't mean to specify that, but was in a rush. Discard that.

LamaBot

Consider this simple program:

#include <iostream>
#include <string>
 
int main() {
 
    std::string firstName;
    std::string lastName;
    std::cout << "Please enter your first and last name" << std::endl;
    std::cin >> firstName >> lastName;
    std::cout << "Hello " << lastName << ", " << firstName << std::endl;
 
    return 0;
}

My output:

Please enter your first and last name
Joe
 
 
 
 
Programmer
Hello Programmer, Joe

Notice all the extra returns I hit? cin kept waiting for data, and until then it refused to print the last line.

By contrast, consider this modification:

#include <iostream>
#include <string>
 
int main() {
 
    std::string firstName;
    std::string lastName;
    std::cout << "Please enter your first name" << std::endl;
    std::cin >> firstName;
    std::cout << "Please enter your last name" << std::endl;
    std::cin >> lastName;
    std::cout << "Hello " << lastName << ", " << firstName << std::endl;
 
    return 0;
}

My output:

Please enter your first name
Joe Programmer
Please enter your last name
Hello Programmer, Joe

Notice how the second line was skipped completely? The first input, cin searched for data, and got "Joe". It stopped, because that's all that was needed, leaving "Programmer" in the buffer.

The second cin picked this up and continued, never giving me the chance to enter some input in the second cin statement.

Without obviously resorting to the first method how would you solve the problem in the second lot of code.

Overall however (All posters) the std:cin.ignore(std::cin.rdbuf()->in_avail() + 1 ) stops the leftover ENTER from being the next input. If the + 1) part of the code is increased by 1 then it effectively does that procedure twice.

LamaBot, does the + '0' ) move the "starting" position 'n' places from the ENTER press effectively and so the user has to input something or press ENTER 'n-1' (the -1 being due to the reaching of the ENTER character which effectively acts as a key press by the user)

Lol, I hope i have it now and cheers all for your help

>how would you solve the problem in the second lot of code.
There's 2 options: you can either use getline(), which would retrieve a whole line of input, thus effectively clearing the input buffer (assuming of course, that it was already clear to begin with).

The other method involves using cin.ignore to discard remaining characters in the buffer, so that cin >> has nothing to grab and is forced to wait for the user to type something...

The other method involves using cin.ignore to discard remaining characters in the buffer, so that cin >> has nothing to grab and is forced to wait for the user to type something...

...Which is essentially what I was saying before. cin is an istream object and as such, it holds different bits to indicate the state of the stream (i.e badbit, eofbit or no bits set) different situations determine what bit is set or no bits set at all; since the extraction operator (>>) is overloaded to accomodate different data types, if you input an invalid character, the badbit is set, for example. The newline ('\n') character is interpreted as a whitespace, which is what cin interprets as a termination character, example:

String a, b;

cin >> a;
cin >> b;

cout << a << ", " << b << endl;

Input:
Hello Buddy
Output:
Hello, Buddy

Doesn't let me input anything because "leading whitespaceBuddy\n" is still in the buffer and the read position is at leading whitespace, which it skips. On the next "cin >>" it eventually reads the '\n', interpreting it as a whitespace, and terminates - which doesn't allow you to input anything. No state bits would be sit, which indicate a sucessful extraction. The "cin.ignore(cin.gtbuf->in_value+1)" sets the read position from the leading whitespace to after the leftover newline, allowing the user to input.

Good luck, LamaBot

Speaking of bad bits, it's often a good idea to use cin.clear() before cin.ignore() (and/or before getting input) simply to make sure that the input stream is functioning as it should. However, there are not that many cases where this is absolutely necessary.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.