Episode 007 – Handling EOF with std::getline

After coming across a coding challenge that required knowing how to properly read a file from stdin and print it back to stdout, I realized that I had to look up this seemingly basic task. And yet it’s one of those things that a developer usually takes for granted in a large project. You’re often building on thousands of lines of infrastructure with small details like handing input from stdin either already taken care of or made redundant by file I/O, RPC systems and networking.

Perhaps unsurprisingly as a result, there a few completely documented solutions to this problem on the open web. Most example code demonstrates how to use std::getline() to retrieve input line by line. This works great for lines from 1 to N-1 because you can just assume each of those lines are newline terminated. But what about line N? If it ends in a newline, std::getline() will remove it when it returns the line. But std::getline() will also return the complete line when it encounters EOF. And in both cases, the next call to std::getline() will signal an error. StackOverflow realizes this here, but hadn’t determined a good answer when I checked.

It took some experimenting but the solution I came up with is featured in my YouTube video above and in the code sample below. Simply put, calling std::istream::peek() with each loop will cause the istream object to trip on an EOF condition. We can detect when this is not the case and safely assume a newline was present in the original input.

std::string s;
while (std::getline(std::cin, s)) {
    // Print out the line we just read.
    std::cout << s;

    // Peek ahead one character for an end of file.
    if (std::cin.peek() != std::char_traits::eof()) {
        // Not EOF. Safe to print a newline here.
        std::cout << std::endl;
    }
}

Thanks for coming back after my extended hiatus from posting last summer. I’m going to try some more short form content like this post and video to get back into the groove of generating content. As always, if you like what you see then subscribe to the video channel, like these posts and send me your comments! I’m always open to suggestions on the videos and topics to cover in future installments.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s