开发者

Convert from C++ style printing to my_printf()

C++ purists may want to look away now. You will hate this.

I have been given an open source windows console app that I am merging with a pre-existing, very old, very large windows app of my own. My old program started life as pure C though recently has been tweaked so that it can compile as C++. My program makes extensive use of a my_printf() function which prints text to a window.

The old console app does its printing C++ style via streams (I have never used this type of printing mechanism before).

When converting the console app to work under my system I could manually edit all the lines that do printing so that they use my_printf() instead. But before I embarked on that I thought I'd just check with StackOverflow to see if I was missing a trick. For example I could imagine somehow letting the C++ prints be done via the stream and then somehow scooping the final text somewhere and then calling my_printf() with the result. Might that be possible?

EDIT: please note my knowledge of C++ is extremely limited and I may need to look some things up in order to understand your answers so please use language that facilitates开发者_JAVA百科 this.


There's indeed a trivial trick. But C++ impurists will hate the fact that C++ has a pure solution ;)

std::ostream is responsible for formatting, but not printing itself. That's handled by std::streambuf. std::cout combines a std::ostream formatter with a std::streambuf-derived object that writes to stdout.

However, you can change the streambuf backing an ostream with ostream::rdbuf(newbuf). As std::cout is just another ostream, you can replace its streambuf too. In this case, you only need to come up with a streambuf-derived class that writes already-formatted output to my_printf(). That should be quite trivial.


You might find string streams useful. For example:

std::ostringstream os;
os << "Print " << whatever << data;
my_printf( "%s", os.str().c_str() );

In case you were feeling adventurous, you could write your own streambuf instead that used my_printf underneath, and inject it into the stream object that is currently used in output statements (e.g. std::cout). Be warned that this latter approach might not be trivial, however it would result in almost no changes to existing codebase.


Subclass std::ostream and make operator << call my_print_f(). You can use internal stringstream in your stream to retrieve string representation of operator << arguments.

Then you'd just have to do find&replace, replacing cout (or whatever stream you directed your output to in the console app) with an instance of your stream class.


Something along these lines might be helpful:

http://www.codeproject.com/KB/debug/debugout.aspx

Should be obvious where the meat of it is, so you can make it print via your own systems, or what have you. In theory, you'd need only search for references to std::cout and replace them with references to your own object.


Overloading the global operator<< is probably what will solve your problem:

#include <iostream>
#include <cstdio>

static int
my_printf (const char* s)
{
  printf ("my_printf: %s\n", s);
}

namespace std {
    std::ostream& operator<< (std::ostream& out, const char* s)
    {
      my_printf (s);
      return out;
    }
}

int
main ()
{
  std::cout << "hello, world"; // => my_printf: hello, world
  return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜