浮动到std :: string转换和本地化

时间:2014-12-02 09:23:23

标签: c++ decimal locale

从float到std :: string的转换是否会受到当前系统区域设置的影响?

我想知道上面的代码是否可以在Germal语言环境下以“1234,5678”而不是“1234.5678”的形式产生输出,例如:

std::string MyClass::doubleToString(double value) const
{
    char fmtbuf[256], buf[256];
    snprintf(fmtbuf, sizeof(fmtbuf)-1, "%s", getDoubleFormat().c_str());
    fmtbuf[sizeof(fmtbuf)-1] = 0;
    snprintf(buf, sizeof(buf)-1, fmtbuf, value);
    buf[sizeof(buf)-1] = 0;

    return std::string(buf);
}

static std::string const& getDoubleFormat() { return "%f"; }

如果是,如何防止这种情况?如何在表单中输出:“1234.5678”用点来分隔小数?

1 个答案:

答案 0 :(得分:1)

标准C库的 <locale> 本地化会影响 格式化输入/输出操作及其字符转换规则和数字格式设置中的小数点字符集。

// On program startup, the locale selected is the "C" standard locale, (equivalent to english). 
printf("Locale is: %s\n", setlocale(LC_ALL, NULL));
cout << doubleToString(3.14)<<endl;
// Switch to system specific locale 
setlocale(LC_ALL, "");  // depends on your environment settings. 
printf("Locale is: %s\n", setlocale(LC_ALL, NULL));
cout << doubleToString(3.14) << endl;
printf("Locale is: %c\n", localeconv()->thousands_sep);
printf("Decimal separator is: %s\n", localeconv()->decimal_point); // get the point 

结果是:

Locale is: C
3.140000
Locale is: French_France.1252
3,140000
Decimal separator is: ,

如果您选择C ++格式化功能,那么 C++ <locale> 更强大,更灵活。但请注意,C语言环境的设置不会影响C ++语言环境:

cout << 3.14<<" "<<endl;   // it's still the "C" local 
cout.imbue(locale(""));    // you can set the locale only for one stream if desired
cout << 3.14 << " "<<1000000<< endl; // localized output

<强>注:

以下内容存在问题:

static std::string const& getDoubleFormat() { return "%f"; }

该函数应返回对字符串的引用。不幸的是,您返回的字符串文字"%f"类型为const char[3]。这意味着存在一个隐式转换,它将从string构造一个临时const char*并返回其引用。但临时对象在表达式结束时被销毁,因此返回的引用不再有效!

为了测试,我按价值返回。