One Unified Global Perspective
Communications with a Global Perspective
Home
Intro
Contact Us
Voice over IP
PBX Solutions
Services
Support
Glossary
Open Source
Blog
Forum

WebMail





2008 Jan 28 - Mon

C++ Override std::cout, std::cerr Streams

C# has a handy method of redirecting Console output. In the first place, C# has a System.Console library for catching all console based output. The Console.SetIn and Console.SetOut methods can then be used to redirect input/output from/to local application based routines.

In C on a Linux/Unix system one can use popen(), as described in question 19.30 of the comp.lang.c FAQ. If you cruise through the FAQ, other methods are discussed and critiqued.

	extern FILE *popen();
	sprintf(cmdbuf, "sort < %s", datafile);
	fp = popen(cmdbuf, "r");
	/* ...now read sorted data from fp... */
	pclose(fp);

Some have suggested using the freopen() stdio function call to redirect stdout to a file. I havn't seen an example to get the stream back into the program though.

In C++, when using the Standard Templated Libraries (STL), one encounters the std::cout and std::cerr streams for standard console output.

C++ streams are generic and, after a fashion, interchangeable. Each stream type has a std::streambuf, which can be redirected. Be aware the streambuf is a C++ construct, and therefore won't catch stuff done with a printf or similar. A pipe may help for the printf problem (I havn't looked into that), but a pipe isn't necessary for the streambuf solution.

A simplistic mechanism for switching streambufs is found in a Borland CPP Builder Forum. An example there does show a good mechanism for saving the old streambuffer before redirecting to the new one. The problem with the posted example is that one has to come back to the streambuf and manually extract what was there. A better solution would do a proper override and automatically process the arriving characters.

I saw in a few places there people were trying to override endl or << operators. That isn't quite correct either.

Probably the best description on how to do a proper override is located in a recent blog entry from Sean Middleditch in a post called: Creating Custom C++ Output Streams. His examples build a simple override and then add additonal features on to improve the solution.

// from Sean Middleditch's site
// your log file, lazily declared as a global
ofstream logfile;

// logbuf forwards all output to cerr and logfile
class logbuf : public streambuf {
private:
  // write a string s of length n to standard
  // error and a log file
  int xsputn (char_type* s, streamsize n) {
    cerr.write(s, n);
    logfile.write(s, n);
    return n;
  }
};

int main () {
  // open our log file
  logfile.open("mylog.txt", ios::app);

  // create our log stream
  ostream log(new logbuf());

  // be friendly
  log << "Hello, World!" << endl;

  return 0;
}

For another perspective on the solution, Cay S. Horstmann wrote an article regarding Extending the iostream library. Further down in that article is an example for 'Routing stream output to a debug window'.

Some further background on IOStreams and Stdio can be found in a Dr. Dobbs article by Matthew H. Austern called The Standard Librarian: IOStreams and Stdio.



Blog Content ©2012
Ray Burkholder
All Rights Reserved
ray@oneunified.net
(441) 500-7292
Available for Contract Work
Resume

RSS: Click to see the XML version of this web page.

twitter
View Ray 
Burkholder's profile on LinkedIn
technorati
Add to Technorati Favorites



January
Su Mo Tu We Th Fr Sa
   
27    


Main Links:
Monitoring Server
SSH Tools
QuantDeveloper Code

Special Links:
Frink

Blog Links:
Sergey Solyanik
Marc Andreessen
HotGigs
Micro Persuasion
... Reasonable ...
Chris Donnan
BeyondVC
lifehacker
Trader Mike
Ticker Sense
HeadRush
TraderFeed
Stock Bandit
The Daily WTF
Guy Kawaski
J. Brant Arseneau
Steve Pavlina
Matt Cutts
Kevin Scaldeferri
Joel On Software
Quant Recruiter
Blosxom User Group
Wesner Moise
Julian Dunn
Steve Yegge
Max Dama

2008
Months
Jan




Mason HQ

Disclaimer: This site may include market analysis. All ideas, opinions, and/or forecasts, expressed or implied herein, are for informational purposes only and should not be construed as a recommendation to invest, trade, and/or speculate in the markets. Any investments, trades, and/or speculations made in light of the ideas, opinions, and/or forecasts, expressed or implied herein, are committed at your own risk, financial or otherwise.