c++fstreamiostreamifstream

How do I handle empty files when dumping ifstream to cout?


I'm trying to dump the contents of a file to cout.

#include <iostream>
#include <fstream>

int main(int argc, char** argv)
{
    if (argc > 1) {
        std::ifstream fin(argv[1]);
        if (fin) {
            std::cout << "---file contents---\n";
            std::cout << fin.rdbuf();
            std::cout << "---end contents---\n";
        } else {
            std::cout << "The file does not exist\n";
        }
    }
    else {
        std::cout << "Usage: " << argv[0] << " FILE\n";
    }
    if (std::cout.good()) {
        return 0;
    }
    else if (std::cout.fail()) {
        return 1;
    }
    else {
        return 2;
    }
}

This code does not work as intended when the input file is empty. It prints the initial "---file contents---", but never prints the trailing "---end contents---". After debugging, I found the application is not crashing, but instead is putting std::cout in an error state (the return code is 1).

How can I print the contents of an empty file without putting cout in an error state?


Solution

  • This operator<< reference (overload number 10 in the list) explains it all:

    If no characters were inserted, executes setstate(failbit).

    Since the input file is empty, there's no characters to insert into the output stream. And the failbit is set.

    You need to add a specific check for failbit after

    std::cout << fin.rdbuf();
    

    to see if the input file was empty or not.