views:

236

answers:

3

Hello all,

I am using stringstream in my entire project which has more than 30 files. I recently overcomed an issue caused by stringstring where I was parsing the double to stringstream and there was a precision lost. So now I want to set the precision for all the files. Is there any way to set it somewhere globally so that I dont need to make changes everywhere going into each file. Someone suggested me to see if its possible using locale.

Please help me out with the issue and if you have code or any link to code, it will be more useful.

+5  A: 

Probably the easiest way to do this is to replace your use of stringstream throughout your program with your own class that inherits from stringstream:

class mystringstream : public std::stringstream
{
public:
   mystringstream()
   {
      precision(16); // or whatever your desired precision is
   }
};

The precision method is defined way up the inheritance chain in std::ios_base, and controls the number of significant digits, or the number of digits after the decimal if the fixed manipulator is in play.

For more example code and output see this paste on codepad.

Patrick Johnmeyer
John Dibling
yeah but I dont want to go in every file and update the stringstream to mystringstream. I am looking for a way to set it using <locale> if possible.
rkb
To the best of my knowledge, there is no way to do this using locale or anything of the sort. I have one or two other ideas I'll try to monkey with if I can find the time.
Patrick Johnmeyer
A: 

Just to add to Patrick's answer, the default precisions for std::ios_base are laid out in the Standard:

27.4.4.1.3:

Table 92: basic_ios::init() effects

Element         Value
rdbuf()         sb
tie()       0
rdstate()       goodbit if sb is not a null pointer, otherwise badbit.
exceptions()    goodbit
flags()         skipws | dec
width()         0
precision()     6
fill()      widen(’ ’);
getloc()        a copy of the value returned by locale()
iarray      a null pointer
parray      a null pointer
John Dibling
A: 

If you are willing to change all of your include statements to your own internal header mystringstream.h, you can use template specialization to pull this off, but with so many caveats I would not do it.

  • You must be sure to use this header everywhere you would have included sstream previously.
  • Your STL implementation must not have already specialized basic_stringstream <char, char_traits<char>, allocator<char> >
  • Your STL implementation, or any other header you include, must not have already instantiated stringstream

That being said, it worked in this simple codepad example.

// mystringstream.h
namespace std
{
  // This class exists solely to "trick" the compiler into
  // considering this allocator a new, different type
  class newallocator : public allocator<char>
  {
  };

  // template specialize std::stringstream to inherit from basic_stringstream
  // using our newallocator in place of std::allocator<char>
  template <>
  class basic_stringstream<char, char_traits<char>, allocator<char> >
    : public basic_stringstream <char, char_traits<char>, newallocator >
  {
  public:
    basic_stringstream()
    {
      precision(16);  // or whatever precision you like
    }
  };
}

I don't personally like this solution because it essentially modifies the behavior of the standard library, instead of extending it.

Patrick Johnmeyer
Patrick Johnmeyer