Skip to main content

Section 11.7 End of File and Getline

What if you do not know how many tokens there are to read? Well, we can simply keep reading until we either encounter the end of the file or produce an error. Trying to read a token once we are at the end of the file will cause the stream to go into a failure state. If we want to try to stop before an input actually fails, we can use the .eof() method to ask β€œare you at the End Of File yet?”. It returns true if the end has been reached. So !streamName.eof() checks β€œis there more to read?”
Listing 11.7.1.
Let’s try the same logic on a list of names:
Data: Names.txt
John Doe Jr.
Maria Cruz
Alice Johnson
Robert Brown
Emily K. Davis
Listing 11.7.2.
Notice that when we read into strings, whitespace still breaks up the tokens. Thus we do not get entire names, we get John, Doe, Jr.,...
We can also use the getline function to read an entire line of text. This is useful when we want to read a whole line of text into a string variable. The getline function takes two parameters: the stream and the string variable to read into. Here is an example:
Listing 11.7.3.

Note 11.7.1.

You can use getline to read an entire line from any stream, including cin. To use it on cin you would do something like getline(cin, stringVariable).
You may notice one extra line of output. That is because the datafile has a newline character after the last name. There is one empty line at the end of the β€œfile”. The getline reads the line for Emily K. Davis and then encounters the newline and stops. The end of file marker is just past that. So the loop runs one more time, reading in a blank line. To fix that, we can try checking the name after reading it in.
Try changing lines 11-12 in the program above to this code:
Listing 11.7.4.
getline(inFile, name); // Read a line from the file
if (name == "") { // Check if the line is empty
    break; // Exit the loop
}
cout << "The next number in the file is: " << name << endl;
Just because a file has lines does not mean you need to use getline to read them. If every line has the same number of pieces of data and those pieces are separated by whitespace, it is likely easier to read in each part directly. For example, given this data:
Data: Cars.txt
Honda Acura 2005
Toyota Camry 2010
Ford Focus 2015
The easiest way to read it in would likely be something like what is shown below. If we used getline we would have to do our own work to then split the line up into parts.
Listing 11.7.5.

Warning 11.7.2.

Mixing getline and >> can cause confusing issues. >> will read the last thing on a line and leave the newline there to be read (or skipped) by the next input instruction. If getline is used next, it will read that newline as an empty line. Try to stick to one method or the other when reading a file.

Checkpoint 11.7.1.

Checkpoint 11.7.2.

You are given a file but it appears that someone’s capslock key was stuck because everything is in uppercase. Write a program that takes the input from the file β€œUPPER.txt” and converts all the text to lower case. Write the definition of the function toLower first. Put the necessary blocks of code in the correct order.
Note that upperToLower intentionally uses pass by value to work with a copy of upper that it can freely modify.
You have attempted of activities on this page.