Re: String formating! Aarrrrgggh.
We're at the point now where we have several developers all working on the
various pieces of C++ code. Some of us are comfortable with Boost, some
use StringStream, and some still use sprintf() and sscanf(). But things
are very inconsistent, and there is too much "glue" code converting between
all the different string representations.
If it matters, our application is largely mathematical, so the bulk of the
string handling that we do is converting floats, ints, and doubles to and
from strings, and we need precise control over the formatting/precision.
Much of this is to/from text files, but some of it is from Win32 objects,
like MFC controls (edit boxes, etc).
- Provide global library functions for the task.
- Be as tolerant as possible in the string to number direction.
- Try to use only std::string and const char* in the interfaces between
modules.
I want to choose a standard and convert all of our existing code. The
choices I'm considering are:
1) std::string, with Boost::format and Boost::tokenizer
I never really got used to it. Maybe it is because the boost libraries
do not compile on all of my preferred compilers.
2) std::string, with StringStream
You don't want to do this. It makes the code rather unreadable.
The iostream libraries are nothing what about C++ should be proud of.
Their design is from the very beginning, maybe to demonstrate the
uncommon operator overloading at that time.
3) MFC's CString (I don't know the sscanf() equivalent here)
If you are a boy scout avoid MFC and ATL. This is mostly a good deed,
especially if portabilitiy might play a role in future.
However, in GUI application you do not always have a reasonable choice.
4) The new sprintf_s() and sscanf_s() "secure" functions available in
Visual Studio
Don't know. Never noticed these functions.
5) Writing a custom string class, along with formatting functions
This depends on your needs. If you want the maximum performance it might
be a good choice. Otherweise rather not.
6) Writing custom formatting functions that work with std::string
I would prefer that.
For usual tasks I do these things based on a custom (v)sprintf derivate
that prints into a std::string. This is a reasonable compromise -
without type safty, but with no buffer overruns.
The implementation is based on vsnprintf. Unfortunately with std::string
this requires to copy the result around in memory. Furthermore it gives
undefined behaviour when the parameters are asynchronously modified by
another thread.
In some projects I use a custom string class that provides a raw_init
function that initializes the string to an uninitialized array of given
length. That is the only function that returns a non-const char pointer
and it is vary useful for adaption of C libraries.
The other direction is easier, since sscanf can be safely applied to
std::string by using c_str().
In your case a set of functions that do completely encapsulate the
conversion from an to floating point numbers, vectors, matrices or
whatever might be the best.
I'm sure there's no one-size-fits-all answer to this problem, so I'm
looking for general feedback. On the other hand, this is such a
fundamental problem in application development that I'm a little surprised
there's no universally accepted solution. Or maybe there is and I just
didn't get the memo.
Well, C++ has a long history. Only 10 years ago still some compilers did
not support std::string out of the box.
And some current C++ programmers are not far behind the first letter of
the language's name. It is also a question of habit.
I still use C style strings in simple parsers too. But I only do this
within the scope of at most one function. Beyond that I only use string
classes. Either std::string or sometimes my own string class.
Marcel