You are here:

C++/Output Help


I wrote this code and it needs to output to the screen as well as a file. Well I can get it to do either or but not both at the same time and ideas and help would be greatly appreciated. Thanks

#include <iostream>

#include <fstream> //Use this program to claculate total tickets sold and total amount collected

#include <iomanip> //Use this with setprecision and showpoint


using namespace std;

int main()


ifstream inData; //Use to read from a file

ofstream outData; //Use to write to a file

double ticketPrice;

double noOfTicketSold;

cout << "Total Tickets and Total Ticket Sales" << endl;

cout << "********************************************" << endl;"k:\inData.txt");"k:\outData.dat");

cout << fixed << showpoint;

cout << setprecision(2);

while( inData >> ticketPrice >> noOfTicketSold)


cout << "Total # of Tickets Sold : " << noOfTicketSold << endl;

cout << "Total Amount Collected  : " << (ticketPrice * noOfTicketSold) << endl;}

cout << "********************************************" << endl;

inData.close();  //Use to close opened files

outData.close(); //Use to close opened files

return 0;


OK the most obvious and easiest way to do this it to literally write all data twice - once to one stream and again to the other:

   std::cout << stuffToBeWritten;
   outData   << stuffToBeWritten;

Obviously this can get a bit tedious, so you could always write to a string stream then write the resultant string to both output streams:

   #include <sstream>

   // ...

   std::ostringstream oStrStrm;

   oStrStrm << "write something" << dataValue << '\n';
   outData   << oStrStrm.str();
   std::cout << oStrStrm.str();

You may need to explicitly flush one or both streams as writing std::endl to std::ostringstream will write newline and 'flush' only the string stream.

These actions could be wrapped up in a simple class, the bare bones of such a class might look as follows:

   #include <sstream>
   #include <ostream>

   class WriteTwoStreams
       std::ostream *      pOut1_;
       std::ostream *      pOut2_;
       std::ostringstream  buffer_;
       WriteTwoStreams( std::ostream & o1, std::ostream & o2 )
       : pOut1_(&o1)
       , pOut2_(&o2)
       std::ostream& out() { return buffer_; }
       void flush();

       ~WriteTwoStreams() { flush(); }        

   void WriteTwoStreams::flush()
       *pOut1_ << buffer_.str();
       *pOut2_ << buffer_.str();
       buffer_.str( "" ); // clear buffered data

This is a _very_ simple scheme and only shows the absolute minimum required to show the idea (e.g. there is absolutely _no_ error checking). The idea is that we create an object of type WriteTwoStreams, passing it the two streams to write to. It holds references (as pointers) to these streams. It also creates a std::ostringstream object to buffer output to until flush is called whereby the buffered characters are written first to one stream then the other then the buffer is cleared. To write data you call the out member function which returns a reference to the buffer string stream. Here is an example of its use:

   #include <iostream>
   #include <fstream>

   // ...

   int main()
       std::ofstream outData("outData.dat");

       WriteTwoStreams tee( outData, std::cout );
       tee.out() << "Hello World!\n"
         << 23 << '*' << 45 << '=' << 23*45
         << std::endl;
       tee.flush();   // *must* flush buffer explicitly in this simple scheme

       tee.out()  << "Another chunk of output!\n";

       tee.flush();   // *must* flush buffer explicitly in this simple scheme

Again error checking has been elided for brevity.

You may be wondering why I called the WriteTwoStreams object tee. This is because there is a UNIX utility with that name that does pretty much what you ask but from the command line:

So if yourProg wrote to standard output (std::cout) then you could use tee form a UNIX command shell like so:

   yourProg | tee outData.dat

The | operator pipes yourProg's standard output to the standard input to tee which writes it to each specified file (just outData.dat here) and to standard output.

If you wish to do a more thorough job then you need to delve into the workings of streams, stream buffers and the like as you would almost certainly need either a specialist stream that held two (output file) stream buffers or a stream buffer that did a similar job that was used with an existing stream type, neither of which are really concise enough topics to go into here - sorry. If you are interested in such matters then I suggest you get yourself a good reference on C++ IOStreams such as the chapter on 'Input/Output Using Stream Classes' in 'The Standard C++ Library a Tutorial and Reference' by Nicolai M. Josuttis or, for even more focus on IOStreams, 'Standard C++ IOStreams and Locales' by Angelika Langer and Klaus Kreft.

However, as a good programmer you should think "has someone done this sort of thing already? And if so can I re-use their work?" before rushing off to try to do it yourself. And indeed they have - a quick query or two in Google will lead you to the Boost IOStreams library (and possibly others). Boost maintain a set of freely available libraries that enhance the standard C++ libraries. Some such libraries make it into newer ISO C++ standards such as the TR1 library extensions. The IOStream library provide a set of code tools to make extending the standard IOStream library easier - and provide a set of such items ready for use. Boost can be found at:

The documentation for the Boost IOStream library (or the most recent release at the time of writing) can be found at:

This is a little daunting, but poking around reveals a set of tee types and functions which can be used to do what we wish. Here is a simple example which in fact writes to two files and std::cout:

   #include <boost/iostreams/tee.hpp>
   #include <boost/iostreams/device/file.hpp>
   #include <boost/iostreams/filtering_stream.hpp>
   #include <iostream>

   // Short alias for boost::iostream namespace
   namespace io = boost::iostreams;

   int main()
       io::filtering_ostream teeOut;

       teeOut.push( io::tee(io::file_sink("out1.txt")) );
       teeOut.push( io::tee(io::file_sink("out2.txt")) );
       teeOut.push( std::cout );
       teeOut << "Hello World!\n"
         << 23 << '*' << 45 << '=' << 23*45
         << std::endl;

       teeOut << "Another chunk of output!" << std::endl;      

I am not going to explain how this works in detail as you can look up the parts in the Boost documentation to see what I am using. The basics are that we use a special output stream provided by the Boost IOStream library - the filtering_ostream. This allows us to attach a chain of filters and a stream to the stream. Data is filtered through the filters before being written to the output stream. So in this case I specify two tee 'filters' to output to different files (using Boost IOStream library file_sinks) and then finally to output the result to std::cout. Note that you should specify std::endl to ensure all buffering is flushed before output is to appear on the console.

Hope this at least gives you some food for thought.  


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell


I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.


My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at


©2017 All rights reserved.