#43 Locale problems on windows systems when using double

0.5.0
open
nobody
Value (7)
5
2014-07-17
2012-02-02
gerdba
No

If we are using values of type double in a json object, there are some serializing and
deserializing problems. This happens when the client running on a locale like german or spanish.

Please adapt your code like this:

jsonwriter.cpp:
...
std::string valueToString( double value )
{
char buffer[32];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
_locale_t common_loc = _create_locale(LC_NUMERIC, "C");
_sprintf_s_l(buffer, sizeof(buffer), "%#.16g", common_loc, value);
#else
std::string lc_num = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
sprintf(buffer, "%#.16g", value);
setlocale(LC_NUMERIC, lc_num.c_str());
#endif
char* ch = buffer + strlen(buffer) - 1;
...

jsonreader.cpp
...
bool
Reader::decodeDouble( Token &token )
{
double value = 0;
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);

if ( length <= bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
_locale_t common_loc = _create_locale(LC_NUMERIC, "C");
count = _sscanf_l( buffer, "%lf", common_loc, &value );
#else
std::string lc_num = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
count = sscanf( buffer, "%lf", &value );
setlocale(LC_NUMERIC, lc_num.c_str());
#endif
}
else
{
std::string buffer( token.start_, token.end_ );
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
_locale_t common_loc = _create_locale(LC_NUMERIC, "C");
count = _sscanf_l( buffer.c_str(), "%lf", common_loc, &value );
#else
std::string lc_num = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
count = sscanf( buffer.c_str(), "%lf", &value );
setlocale(LC_NUMERIC, lc_num.c_str());
#endif
...

Related

Bugs: #61

Discussion

  • I was just looking into this too, although calling setlocale isn't an ideal solution as this would affect all threads for the running program.