std::ostream и разделители целой и дробной части
От: Аноним  
Дата: 20.07.06 11:48
Оценка:
Уважаемые Гуру!

Имеется следующая задача. Необходимо перевести double в std::string при этом должна быть возможность
управлять символом разделителя целой/дробной части (точка или запятая). На данный момент в голову пришли 2 решения
1. ручное ковыряние в строке с заменой запятой на точку или наоборот.
2. Использование std::locale.

Оба способа для меня выглядят как-то "не очень красиво". Нет ли какого нибудь решения как с манипуляторами?

Заранее благодарен за ответы.


int main () {

    double d = 0.01;

    std::locale ru_loc ("russian_russia");
    std::cout.imbue ( ru_loc );

    std::cout << "Comma as delimiter : " << d <<  std::endl;

    std::locale en_loc ;
    std::cout.imbue ( en_loc );

    std::cout << "Dot as delimiter   : " << d << std::endl;

    return 1;
}
Re: std::ostream и разделители целой и дробной части
От: korzhik Россия  
Дата: 20.07.06 13:31
Оценка: 3 (1)
Здравствуйте, Аноним, Вы писали:

А>Уважаемые Гуру!


А>Имеется следующая задача. Необходимо перевести double в std::string при этом должна быть возможность

А>управлять символом разделителя целой/дробной части (точка или запятая).

разделителем целой/дробной части управляет фасет std::numpunct, следовательно надо создать свой:
//-----------------------------------------------------------------------------
#include <iostream>
#include <locale>
//-----------------------------------------------------------------------------
class custom_numpunct : public std::numpunct<char>
{
public:
    typedef char        char_type;
    typedef std::string string_type;

    explicit custom_numpunct(size_t refs = 0) : std::numpunct<char>(refs) {}

    static void decimal_point(char_type dec_pt) { m_dec_pt = dec_pt; }

protected:
    char_type do_decimal_point() const { return m_dec_pt; }

private:
    static char_type m_dec_pt;
};

char custom_numpunct::m_dec_pt = '.';
//-----------------------------------------------------------------------------
int main()
{
  std::locale     loc(std::locale::classic(), new custom_numpunct);

  std::cout.imbue(loc);

  std::cout << 123.3123 << '\n';  

  custom_numpunct::decimal_point(',');
  std::cout << 123.3123 << '\n';

  std::cout.imbue(std::locale::classic());
}
Re: std::ostream и разделители целой и дробной части
От: Centaur Россия  
Дата: 20.07.06 15:07
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Имеется следующая задача. Необходимо перевести double в std::string при этом должна быть возможность

А>управлять символом разделителя целой/дробной части (точка или запятая). На данный момент в голову пришли 2 решения
А>1. ручное ковыряние в строке с заменой запятой на точку или наоборот.
А>2. Использование std::locale.

Программу не должно волновать, какой разделитель использовать. Если значение вводится/выводится для пользователя, то использовать дефолтную локаль. Если для сериализации — то локаль C.
Re[2]: std::ostream и разделители целой и дробной части
От: Аноним  
Дата: 20.07.06 21:55
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Программу не должно волновать, какой разделитель использовать. Если значение вводится/выводится для пользователя, то использовать дефолтную локаль. Если для сериализации — то локаль C.



В данной ситуации проблема заключается не столько в локали, установленной на машине enduser-a, сколько в "стандарте", который он используест при оформлении конструкторской документации. Если используешь наш ЕСКД, то будь любезен, ставь запятую в качестве разделителя целой/дробной частей, даже если сидишь не в России. И наоборот.

PS Спасибо korzhik-у за исчерпывающий ответ. Иду изучать фасеты
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.