Suppose you have a file that contains student grades and names:
82 Dave
93 Scottie
88 Bob
75 Ginger |
Here is a first attempt of a program that reads the grades and prints them out:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
int
main()
{
int grade;
while (cin >> grade) {
cout << grade << '\n';
cin.ignore(30, '\n'); // ignore 30 characters or until you ignore a newline
}
return 0;
}
|
Line 13 extracts and discards characters from cin until it extracts 30 characters, or it extracts a '\n' character, or it reaches the end of the stream. Note that the '\n', if seen, will be extracted and discarded. So the next character you try to read is the one after the '\n'.
So far so good, when I run the program on the above input, I get this:
But what if the first name is really long?
82 Mr. David M Hayden of the great state of New Jersey. |
Now when I run the program it just prints 82. Why? Because it ignored 30 characters without seeing a '\n'. The name is longer than 30 characters so it stopped there. The next time through the loop, it wasn't able to extract a grade number because it the next characters in the stream were letters.
What to do? We can increase to 30 to something bigger, line 100. But what's to prevent the name from being larger than 100 characters. How about 1000 characters? Surely no name will be longer than that. But what if some hacker decides to feed the program bad input and deliberately creates a file a "name" that's 1001 characters? Or 100,000 characters? Or 1,000,000 characters?
You want to ignore the most characters that could possibly be in the stream. And that number is the maximum value of type type streamsize. You can get this value portably using the numeric_limits template:
numeric_limits<streamsize>::max()
.
Here is a reference for ignore():
http://www.cplusplus.com/reference/istream/istream/ignore/