Boost logo

Boost :

From: Derek Ross (dross_at_[hidden])
Date: 2002-08-20 16:14:02


Is there still interest in printf-styled formatting capabilities in boost?

I just joined the mailing list, but from what I can tell from the
archives, there was much debate about how to implement the format
function in a syntactically agreeable manner.

Here's a toy example of another technique, that hopefully hasn't been
discussed already. It lets you format output like so:

   format(cout, "%d %x %o") << 1234 << 456 << 789;

This code only accepts %d, %x, %o, %c and %p as format identifiers, with
no variations (padding, width, etc) whatsoever. ( It's more of a proof
of concept.) It works with g++ 2.96.

Derek.

========================================================

#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <string.h>

using namespace std;

class format
{
public:
        
        ostream& os; // the actual ostream that is written to.
        const char* fmt; // format string.
        
        int index; // index within the format string.
        
        format(ostream& a_os, const char* a_fmt) // ctor.
        :os(a_os), fmt(a_fmt), index(0)
        {}
        
        template<class T>
        format& operator<<(T a)
        // scan 'fmt' for formatting information, apply it to 'os',
        // then write 'a' to 'os'.
        {
                bool done_pre=false;
                bool done_post=false;
                
                while(!done_pre) // scan and print chars preceding a %
                {
                        if(index>=strlen(fmt))break;
                        
                        if(fmt[index] != '%')
                        {
                                os << fmt[index];
                                
                        }
                        else
                        {
                                done_pre=true;
                        }
                        index++;
                }
                                
                if(index<strlen(fmt)) // apply formatting to os and print 'a'.
                {
                        switch(fmt[index])
                        {
                                case 'p': os << (void*)(a); break;
                                case 'c': os << char(a) ; break;
                                case 'x': os << hex << a; break;
                                case 'd': os << dec << a; break;
                                case 'o': os << oct << a; break;
                        }
                        index++;
                }
                else
                {
                        // no more formatting, print anyways.
                        os << a;
                }
                                
                while(!done_post) // scan and print chars following a %
                {
                        if(index>=strlen(fmt))break;
                        
                        if(fmt[index] != '%')
                        {
                                os << fmt[index];
                                index++;
                        }
                        else
                        {
                                done_post=true;
                        }
                }
                
                return *this;
        }
};

void main()
{

        format(cout, "\ndecimal:%d, hex:%x, octal:%o\n\n") << 1234 << 1234 << 1234 ;
        
        format(cout, "pointer:%p, char:%c\n\n") << 1234 << 88 ;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk