Установка точности для строкового потока в глобальном масштабе - PullRequest
6 голосов
/ 04 марта 2010

Я использую stringstream во всем моем проекте, который содержит более 30 файлов.Недавно я преодолел проблему, вызванную stringstring, когда я анализировал double для stringstream, и была потеряна точность.Итак, теперь я хочу установить точность для всех файлов.Есть ли способ установить его где-нибудь глобально, чтобы мне не нужно было вносить изменения везде, входя в каждый файл.Кто-то предложил мне посмотреть, возможно ли использование локали.

Пожалуйста, помогите мне решить эту проблему, и если у вас есть код или какая-либо ссылка на код, это будет более полезно.

Ответы [ 3 ]

7 голосов
/ 05 марта 2010

Вероятно, самый простой способ сделать это - заменить использование потока строк в вашей программе собственным классом, который наследуется от stringstream:

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

Метод precision определен вверх по цепочке наследования в std::ios_base и управляет количеством значащих цифр или числом цифр после десятичной дроби, если манипулятор fixed находится в игре.

Для получения дополнительной информации о коде и выводе см. эту вставку на кодовую панель.

1 голос
/ 05 марта 2010

Просто чтобы добавить к ответу Патрика, стандартные значения для std::ios_base изложены в стандарте:

27.4.4.1.3:

Таблица 92: basic_ios :: init () эффекты

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
0 голосов
/ 06 марта 2010

Если вы хотите изменить все свои операторы включения на собственный внутренний заголовок mystringstream.h, вы можете использовать специализацию шаблонов, чтобы выполнить это, но с таким большим количеством предостережений я бы этого не сделал.

  • Вы должны обязательно использовать этот заголовок везде , который вы бы включили sstream ранее.
  • Ваша реализация STL не должна уже специализироваться basic_stringstream <char, char_traits<char>, allocator<char> >
  • В вашей реализации STL или любом другом заголовке, который вы включаете, не должно быть уже созданного потока строк

Как говорится, в этом простом примере кодовой панели .

// 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
    }
  };
}

Мне лично не нравится это решение, потому что оно существенно изменяет поведение стандартной библиотеки, а не расширяет его.

...