My textbook recommends using the member accessor method iStreamVar.eof()
when dealing with textual data and while (iStreamVar)
when dealing with numeric data.
Can someone please explain why it would matter?
Quote from book:
Using the function eof to determine the end-of-file status works best if the input is text. The earlier method of determining the end-of-file status works best if the input consists of numeric data.
That is the only thing mentioned on the topic. After this, it just explains how the process works.
CodePudding user response:
Which method you use for determining the end of data depends on how you use it. My guess is, both methods which your textbook mentions are used wrong, so they fail in different situations. That's why it recommends using different methods in different situations.
The correct method is not trivial, and it depends on how important error resilience is for you.
If you want to read a space-delimited stream with numbers in it, and you are sure the file contains no errors, the code is simplest:
int value;
while (iStreamVar >> value)
{
...
}
Note that it's not any of the two original options.
If your file contains space-delimited textual data, and you are sure there are no errors, use the same code (but declare the temporary variable as string
instead of int
).
If you want to detect and recover from errors, use more elaborate code. But I cannot recommend you any specific code structure - it depends on what exactly you want to do in case of errors. Also:
- Are text records delimited by space or newline?
- What if the input text-file contains an empty line?
- Numbers - floating-point or not?
- Numbers - if there is a stray character like
a
among number data, what to do?
So there is no single correct recipe for doing proper input with error resilience.
CodePudding user response:
Unless there is something significant in the context that isn't shown in the question, that quote is nonsense.
The way to read from a file and check for success is to read from the file:
int data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::getline(std::cin, data)
std::cout << "read succeeded, value is " << data << '\n';
If an attempted read fails you can call .eof()
to find out whether the failure was because the input was at the end of the file. Contrary to what some beginners expect (and what some languages do), if .eof()
returns false it does not mean that there is data remaining in the input stream. The stream might be at the end of the file after a successful read consumed the remaining input. .eof()
will return false, but the next attempted read will fail, and after that, .eof()
will return true.
std::stringstream input("1234");
int data;
input >> data; // succeeds
std::cout << input.eof() << '\n'; // outputs 0, no failure
input >> data; // fails, no more input
std::cout << input.eof() << '\n'; // outputs 1, failed because at end of file