Search code examples
c++io

Is there a C++ idiom for writing to either STDOUT or a file?


I'm writing a command line tool and I would like it to write to STDOUT by default, but write to a file if specified. I'm trying to do this in a way that keeps the interface for writing the output consistent by using an output stream.

This was my first idea:

#include <iostream>

int main(int argc, char* argv[]) {
  std::ostream* output_stream = &std::cout;

  // Parse arguments

  if (/* write to file */) {
    std::string filename = /* file name */;

    try {
      output_stream = new std::ofstream(filename, std::ofstream::out);
    } catch (std::exception& e) {
      return 1;
    }
  }

  // Possibly pass output_stream to other functions here.
  *output_stream << data;

  if (output_stream != &std::cout) {
    delete output_stream;
  }

  return 0;
}

I don't like the conditional deletion of the output stream. That makes me think there must be a better way to do the same thing.


Solution

  • A simple way to do this is just write to standard output and let the user use shell redirection to send the output to a file, if desired.

    If you want to implement this in your code instead, the most straightforward way I can think of would be to implement the body of your program in a function that accepts an output stream:

    void run_program(std::ostream & output) {
        // ...
    }
    

    Then you can conditionally call this function with std::cout or a file stream:

    if (/* write to file */) {
        std::ofstream output{/* file name */};
        run_program(output);
    } else {
        run_program(std::cout);
    }