The CIN buffer

I was working through some example programs in the C++ book I'm reading, and decided they are mostly crap because, while they address the topic in the chapter, they do so in a manner that is prone to error.

Author wrote:
1
2
3
4
5
6
7
char ch;
cin >> ch;
while(ch != 'c' && ch != 'p' && ch != 't' && ch != 'g')
{
  cout << "Please enter a c, p, t, or g: ";
  cin >> ch;
}


Better, I thought, is this:

1
2
3
4
5
6
7
8
char ch;
cin.get(ch);
while(ch != 'a' && ch != 'b' && ch != 'c' && ch != 'd')
{
  if (ch=='\n')
    cout << "Invalid input. Please enter a, b, c, or d.";
  cin.get(ch)
}


This way I'm only outputting a single line if the user types in something like "gflkgjflkgtfsg" at the cin prompt, and will process a "correct" entry no matter where it appears in the cin buffer. So if "twerlkjtwretbrewlkjrtw" is their input, the "b" will get processed. However, this leaves the cin buffer with a lot of potential garbage.

What I really want is this:
1
2
3
4
5
6
7
cin.get(ch)
while(ch != 'a' && ch != 'b' && ch != 'c' && ch != 'd')
{
  cout << "Invalid input. Please enter a, b, c, or d.";
  cin.ignore(rest of cin buffer); // dump buffer
  cin.get(ch); // new prompt
}


The trouble is that cin.ignore() requires a length (and potentially a delimiter) but I have no idea what that length is. What IS the length of cin?

If I do something like this:
cin.ignore(1024, '\n')
that will work fine for most keyboard input, but what if the cin buffer contains a redirection from a file? Then, there can be many instances of '\n' (well beyond 1024 characters) but still a ton of junk in the cin buffer. It doesn't make sense to check for EOF because if the junk input is from the keyboard, EOF probably won't exist. Further, to supply EOF as a delimiter, I still need to know LENGTH, since a redirected file can be millions of bytes long.

I know I'm over-thinking CIN, but I'm really curious how this has been dealt with traditionally. I suspect there are methods to handle this, but I'm only on chapter 6 of C++; my set of tools to resolve this puzzle is very limited.
Stick with what the author wrote. Add a newline before the message so it looks better.

Another alternative would be:
1
2
3
4
string input;
cout << "Enter a string followed by enter: ";
getline( cin, input );
//... 
Last edited on
closed account (z05DSL3A)
The trouble is that cin.ignore() requires a length (and potentially a delimiter) but I have no idea what that length is. What IS the length of cin?


std::numeric_limits<std::streamsize>::max()
@Zaita -- Your solution is a good one, but not without challenges. At the point where most newbie programmers are writing code with >>, many have not been introduced to string types, and I venture that most have not been introduced to the types in <sstream>. While I agree with your solution overall, sometimes it will not meet the specific needs of the learner. Sincerely, until someone has endured all the heartache associated with >>, I don't think they can fully appreciate your solution and its beauty.
The types introduced in sstream are only used for data conversions in a safe manner.

The getline is a very simple approach. Easier than >> funny enough.
1
2
3
4
5
6
7
8
 string input = "";

 // How to get a string/sentence with spaces
 cout << "Please enter a valid sentence (with spaces):\n>";
 getline(cin, input);
 cout << "You entered: " << input << endl << endl;

 if (input == "a") // etc. 


Easy, and you won't have to worry about left over characters in the stream.
Topic archived. No new replies allowed.