hitcounter
dpointer
Thursday, July 14, 2005
 
Logging to String

It it easier for later troubleshooting if your classes have logging facility, or at least a special member function used to dump their state. Since we might not want to dump always to screen, a logical declaration would be:

void FooBar::dump( std::ostream& out ) const

since we can call it with instance->dump( std::cout ) and it will output to screen.

Suppose there are many instances of different classes, they are arranged in a tree, and we want to call all those dump. Would be easier to trace if the output is arranged also like a tree, i.e. with different indentation to mark different depth level:

Root
(dump output of root class)

      Container 1
      (dump output of the above container)

      Container 2
      (dump output of the above container)

           Node A
          (dump output of this node)


      Container 3
      (dump output of the above container)

The key here is to know the level of the instance and prepend its debug output with proper number of whitespaces. Assuming you have created the spaces already for certain depth level (how to do it is left as an exercise!), then call the dump function not to screen (std::cout), but to a local buffer instead and later on add some spaces.

  std::ostringstream t;
  instance->dump( t );
  std::string d = t.str();
  std::cout << spaces;
  for( unsigned i = 0; i < d.size(); i++ )
    if( d[i] != '\n' )
      std::cout << d[i];    
    else
      std::cout << std::endl << spaces;

The trick here is the use of std::ostringstream (so do no forget to include sstream) to allow dumping to a string buffer, than manipulate the buffer so that spaces (of course needs to be constructed beforehand) is outputted at the beginning and after each end-of-line.



Powered by Blogger