From printf to C++ formatting

Discussion in 'C++' started by Steven T. Hatton, Aug 1, 2005.

  1. OK, I take back the nasty stuff I said about printf. At least until I see a
    similarly concise way of writing this using C++ formatters. I want to
    convert the following to something I can put onto a C++ std::eek:stream:

    printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x %02x\n",
    i,
    std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    SectionTypes( pSec->GetType() ).c_str(),
    pSec->GetAddress(),
    pSec->GetSize(),
    pSec->GetEntrySize(),
    SectionFlags( pSec->GetFlags() ).c_str(),
    pSec->GetLink(),
    pSec->GetInfo(),
    pSec->GetAddrAlign() );

    One option I've looked at, and may come back to, is the Boost.Format
    library. For now, I want to see if I can find a reasonably elegant way of
    using the C++ format manipulators. Does anybody have a systematic approach
    to this kind of situation?
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Aug 1, 2005
    #1
    1. Advertising

  2. Steven T. Hatton wrote:
    > OK, I take back the nasty stuff I said about printf. At least until I see a
    > similarly concise way of writing this using C++ formatters. I want to
    > convert the following to something I can put onto a C++ std::eek:stream:
    >
    > printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x %02x\n",
    > i,
    > std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    > SectionTypes( pSec->GetType() ).c_str(),
    > pSec->GetAddress(),
    > pSec->GetSize(),
    > pSec->GetEntrySize(),
    > SectionFlags( pSec->GetFlags() ).c_str(),
    > pSec->GetLink(),
    > pSec->GetInfo(),
    > pSec->GetAddrAlign() );
    >
    > One option I've looked at, and may come back to, is the Boost.Format
    > library. For now, I want to see if I can find a reasonably elegant way of
    > using the C++ format manipulators. Does anybody have a systematic approach
    > to this kind of situation?


    With C++ io manipulators it would look ugly and much more error-prone
    then a simple format string. The only trouble with printf is that it's
    not type safe and it requires experience to know its pitfalls and use
    it safely.

    C++ standard streams and formatting are really clumsy.
     
    Maxim Yegorushkin, Aug 2, 2005
    #2
    1. Advertising

  3. Steven T. Hatton

    Earl Purple Guest

    Maxim Yegorushkin wrote:
    > With C++ io manipulators it would look ugly and much more error-prone
    > then a simple format string. The only trouble with printf is that it's
    > not type safe and it requires experience to know its pitfalls and use
    > it safely.
    >
    > C++ standard streams and formatting are really clumsy.


    That's why you can use boost::format which has the advantages of printf
    and uses printf formatting, but also doesn't have the disadvantages of
    the lack of type-safety and extensibility. (Extensibility in the type
    of streams, not the type of data that can be given a formatting code).

    (You can always extend your own objects to produce strings, of
    different formats if required).
     
    Earl Purple, Aug 2, 2005
    #3
  4. Steven T. Hatton

    Earl Purple Guest

    Steven T. Hatton wrote:
    > OK, I take back the nasty stuff I said about printf. At least until I see a
    > similarly concise way of writing this using C++ formatters. I want to
    > convert the following to something I can put onto a C++ std::eek:stream:
    >
    > printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x %02x\n",
    > i,
    > std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    > SectionTypes( pSec->GetType() ).c_str(),
    > pSec->GetAddress(),
    > pSec->GetSize(),
    > pSec->GetEntrySize(),
    > SectionFlags( pSec->GetFlags() ).c_str(),
    > pSec->GetLink(),
    > pSec->GetInfo(),
    > pSec->GetAddrAlign() );
    >
    > One option I've looked at, and may come back to, is the Boost.Format
    > library. For now, I want to see if I can find a reasonably elegant way of
    > using the C++ format manipulators. Does anybody have a systematic approach
    > to this kind of situation?


    In this particular instance though you have a lot of calls to pSec. Now
    you might want to keep this a free function rather than a member
    function, and maybe the class is not your own.

    However it is inflexible as you can only output to the console or
    wherever the console is redirected to. Also are you always going to
    output to this particular format or are you going to modify it? And
    remember type-safety - if, for example, you allow users to pick their
    own format string so they can output in different formats, and their
    format string doesn't comply with your function, then it will still
    compile beautifully but could go "bang!" when you run it.

    pSec is obviously a pointer to something, and it can't be NULL, and
    presumably it only reads and the class it reads from is const-correct
    so I'd change from a pointer to a const reference.

    Next, if you really feel you must output then use sprintf - at least
    here you know how big a buffer you need, so then you can get your
    function to return what you have constructed converting it to a
    std::string. (But I would go with boost::format).

    Alternatively, your function could take an ostream& parameter and
    return it. If the user wants a string they will use ostringstream. If
    this is the only way you are ever going to format the object then you
    may as well make this

    std::eek:stream & operator<<( std::eek:stream &, const Section & );

    Assuming Section is the name of your class. (As the first element i is
    probably unrelated you would stream that in separately).
     
    Earl Purple, Aug 2, 2005
    #4
  5. Steven T. Hatton

    __PPS__ Guest

    If I were you I'd use boost.format :)

    here's how:
    #include <boost/format.hpp>

    class pSec_Class {
    ...
    ...
    friend std::eek:stream& opeartor<<
    (std:eek:stream& os, const pSec_Class &x){
    static boost::format frmt("your %1% format %2% string .?"
    "some other vars?..");
    os << frmt % x.GetType().c_str() % x.GetSize(); // ...
    return os;
    }
    };

    ....
    std::cout << *pSec << std::endl;
     
    __PPS__, Aug 2, 2005
    #5
  6. __PPS__ wrote:

    > If I were you I'd use boost.format :)
    >
    > here's how:
    > #include <boost/format.hpp>
    >
    > class pSec_Class {
    > ...
    > ...
    > friend std::eek:stream& opeartor<<
    > (std:eek:stream& os, const pSec_Class &x){
    > static boost::format frmt("your %1% format %2% string .?"
    > "some other vars?..");
    > os << frmt % x.GetType().c_str() % x.GetSize(); // ...
    > return os;
    > }
    > };
    >
    > ...
    > std::cout << *pSec << std::endl;


    I probably should have worked through using the Boost.Format library. It
    started looking a bit obscure when I tried to write it all out. What I
    ended up doing was using brute force and C++ manipulators. It's not too
    terribly ugly. I did create an operator<<() similar to what you show
    above. Once I realized that there are two different things called `hex',
    one being std::hex, and the other being ios_base::hex, and that one is a
    value while the other is a function, things became much easier. That is a
    gotch from hell. I couldn't figure out, for the life of me, why the
    manipulator was not changing the format, but, instead, simply printing as a
    numerical value.
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Aug 2, 2005
    #6
  7. Steven T. Hatton

    __PPS__ Guest

    As far as I remember boost.format supports printf-like syntax. Probably
    you can do like this:
    static boost format frmt("printf-like string");
    ....
    read docs for boost.format
     
    __PPS__, Aug 2, 2005
    #7
  8. Steven T. Hatton

    __PPS__ Guest

  9. Steven T. Hatton a écrit :
    > OK, I take back the nasty stuff I said about printf. At least until I see a
    > similarly concise way of writing this using C++ formatters. I want to
    > convert the following to something I can put onto a C++ std::eek:stream:
    >
    > printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x %02x\n",
    > i,
    > std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    > SectionTypes( pSec->GetType() ).c_str(),
    > pSec->GetAddress(),
    > pSec->GetSize(),
    > pSec->GetEntrySize(),
    > SectionFlags( pSec->GetFlags() ).c_str(),
    > pSec->GetLink(),
    > pSec->GetInfo(),
    > pSec->GetAddrAlign() );
    >
    > One option I've looked at, and may come back to, is the Boost.Format
    > library. For now, I want to see if I can find a reasonably elegant way of
    > using the C++ format manipulators. Does anybody have a systematic approach
    > to this kind of situation?


    Is not your purpose vain?
    Formatting has been well done once with printf specifications.
    I do not think that C++ formatters are intended to replace printf
    formatting, but to allow a quick not-so-well formatted output.
    But if you want to well control printing, it is easier to turn back to
    printf-like formatting.
    Please note that it is what MS has done with its CString::Format()
    Anyway, what seems to me missing is a bridge between printf-like
    formatting and <string>.
     
    Pierre Couderc, Aug 4, 2005
    #9
  10. Pierre Couderc wrote:

    > Steven T. Hatton a écrit :
    >> OK, I take back the nasty stuff I said about printf. At least until I
    >> see a similarly concise way of writing this using C++ formatters. I want
    >> to convert the following to something I can put onto a C++ std::eek:stream:
    >>
    >> printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x %02x\n",
    >> i,
    >> std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    >> SectionTypes( pSec->GetType() ).c_str(),
    >> pSec->GetAddress(),
    >> pSec->GetSize(),
    >> pSec->GetEntrySize(),
    >> SectionFlags( pSec->GetFlags() ).c_str(),
    >> pSec->GetLink(),
    >> pSec->GetInfo(),
    >> pSec->GetAddrAlign() );
    >>
    >> One option I've looked at, and may come back to, is the Boost.Format
    >> library. For now, I want to see if I can find a reasonably elegant way
    >> of
    >> using the C++ format manipulators. Does anybody have a systematic
    >> approach to this kind of situation?

    >
    > Is not your purpose vain?
    > Formatting has been well done once with printf specifications.
    > I do not think that C++ formatters are intended to replace printf
    > formatting, but to allow a quick not-so-well formatted output.
    > But if you want to well control printing, it is easier to turn back to
    > printf-like formatting.
    > Please note that it is what MS has done with its CString::Format()
    > Anyway, what seems to me missing is a bridge between printf-like
    > formatting and <string>.


    But how do you use printf with std::eek:stream? The biggest obstacle I've
    found with the C++ formatters is that there is no way that I am aware of to
    truncate with them.
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Aug 4, 2005
    #10
  11. In message <>, Pierre Couderc
    <> writes
    >Steven T. Hatton a écrit :
    >> OK, I take back the nasty stuff I said about printf. At least until I see a
    >> similarly concise way of writing this using C++ formatters. I want to
    >> convert the following to something I can put onto a C++ std::eek:stream:
    >> printf( " [%2x] %-20s %-8.8s %08x %06x %02x %-3.3s %02x %04x
    >>%02x\n",
    >> i,
    >> std::string( pSec->GetName() ).substr( 0, 20 ).c_str(),
    >> SectionTypes( pSec->GetType() ).c_str(),
    >> pSec->GetAddress(),
    >> pSec->GetSize(),
    >> pSec->GetEntrySize(),
    >> SectionFlags( pSec->GetFlags() ).c_str(),
    >> pSec->GetLink(),
    >> pSec->GetInfo(),
    >> pSec->GetAddrAlign() );
    >> One option I've looked at, and may come back to, is the Boost.Format
    >> library. For now, I want to see if I can find a reasonably elegant way of
    >> using the C++ format manipulators. Does anybody have a systematic approach
    >> to this kind of situation?

    >
    >Is not your purpose vain?
    >Formatting has been well done once with printf specifications.
    >I do not think that C++ formatters are intended to replace printf
    >formatting, but to allow a quick not-so-well formatted output.


    I don't see why that should be. You may not like the syntax, but they
    allow pretty much the same degree of control as the printf family.

    Something that C++ streams support which printf doesn't is the principle
    that a class should know best how to format itself. of course it's not
    true for all classes, but when it does apply it's a way of working with
    the available tools instead of trying to work around them. Compare the
    example above with this:

    cout << *pSec;

    >But if you want to well control printing, it is easier to turn back to
    >printf-like formatting.
    >Please note that it is what MS has done with its CString::Format()


    I wouldn't offer *that* as a paradigm of progressive software
    development ;-)

    >Anyway, what seems to me missing is a bridge between printf-like
    >formatting and <string>.


    --
    Richard Herring
     
    Richard Herring, Aug 4, 2005
    #11
  12. Steven T. Hatton

    Howard Guest

    "Steven T. Hatton" <> wrote in message
    news:...


    >
    > But how do you use printf with std::eek:stream? The biggest obstacle I've
    > found with the C++ formatters is that there is no way that I am aware of
    > to
    > truncate with them.
    > --



    You could use sprintf to put it in a char array, then put that on the
    stream.

    (I'd still rather use the streams directly, under control of the class
    instead of external to it like your example, though.)

    -Howard
     
    Howard, Aug 4, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joe Hotchkiss
    Replies:
    1
    Views:
    1,202
  2. ben
    Replies:
    4
    Views:
    622
    Martin Ambuhl
    Jun 26, 2004
  3. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,249
  4. azza

    printf affects following printf/s

    azza, Oct 17, 2010, in forum: C Programming
    Replies:
    0
    Views:
    433
  5. guru
    Replies:
    8
    Views:
    284
Loading...

Share This Page