Boost logo

Boost :

Subject: Re: [boost] [locale] Review
From: Artyom (artyomtnk_at_[hidden])
Date: 2011-04-16 04:45:53


----- Original Message ----
> From: Noah Roberts <roberts.noah_at_[hidden]>
>
> Actually, I ran into what I would call a bug.
>
> #include <boost/locale.hpp>
> #include <boost/lexical_cast.hpp>
>
> #include <iostream>
>
> using namespace boost::locale;
>
> int main()
> {
> generator gen;
>
> std::locale::global(gen("fr_CA.UTF-8"));
> //std::locale::global(std::locale(""));
>
> std::string dbl = boost::lexical_cast<std::string>(3.14);
> std::cout << dbl << std::endl;
>
> std::cin.get();
> }
>
> My language settings currently use ',' as decimal separator as do the settings
>for
> the french (Canada) language settings.
>
> The commented out version outputs "3,14000000001".
> This is what I would expect to happen. The boost::locale version
> outputs "3.14000000001".
>
> It looks to me like the punctuation stuff isn't being set up correctly.
> The as::number thing doesn't do anything either. Only locale::format catches
>on
> and does it right.

I'll explain, it is not a bug it is a feature.

1st of all read this:
http://cppcms.sourceforge.net/boost_locale/html/std_locales.html

http://cppcms.sourceforge.net/boost_locale/html/std_locales.html#std_locales_common

Boost.Locale preserves default formatting as C/POSIX locale and it is very
important.

I've seen many libraries become broken because of setting gobal locale, consider
cvs generation.

So in order to generate localized number you should use as::number and in your
case you also missed imbuing a locale object to cout.

So by default numbers generated in "C" format so you sql library that
binds

   sql << "SELECT values from FOO where bar > ?", 3.14; // SOCI example

would not be broken, because the statement would be
  
   "SELECT values from FOO where bar > 3,14"

in some locales.
 
And I've seen lots of code that fails in such
case just because 95% of programmers unaware of the fact the number
may be localized.

The problem with C even more severe, because unlike C++, C libraries
have no option to imbue a locale and setting global C++ locale

 std::locale::globale(std::locale(""))

Would call setlocale(LC_ALL,"");

And it would totally mess C libraries that use sprintf to format numbers
and get "," instead of "."

So if you need localized numbers you should use as::number otherwise
C/POSIX locale is used by default.

It is by design.

Artyom


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk