今天遇到一个问题,使用std::ostringstream拼装字符串,发现所有的整形打印出来后都是以逗号分隔的形式,即对于整数3600 输出为: 3,600
每隔三位就会自动加上一个逗号,这样导致接受端不能将对应的字符串成功转换回整形,比如上面3,600通过atoi转换就只能得到3了
上网了解了下,这个和程序运行环境的local的设置有关,C++中所有的输入输出流都使用std::local里定义的规则来格式化不同数据,下表是支持的类型:
Supported facets | |
---|---|
std::collate<char> | std::collate<wchar_t> |
std::ctype<char> | std::ctype<wchar_t> |
std::codecvt<char,char,mbstate_t> std::codecvt<char16_t,char,mbstate_t> | std::codecvt<char32_t,char,mbstate_t> std::codecvt<wchar_t,char,mbstate_t> |
std::moneypunct<char> std::moneypunct<char,true> | std::moneypunct<wchar_t> std::moneypunct<wchar_t,true> |
std::money_get<char> | std::money_get<wchar_t> |
std::money_put<char> | std::money_put<wchar_t> |
std::numpunct<char> | std::numpunct<wchar_t> |
std::num_get<char> | std::num_get<wchar_t> |
std::num_put<char> | std::num_put<wchar_t> |
std::time_get<char> | std::time_get<wchar_t> |
std::time_put<char> | std::time_put<wchar_t> |
std::messages<char> | std::messages<wchar_t> |
如下代码设置了数字输出格式,以逗号表示小数点,且每三位数字以点号分隔:
class my_punct
: public std::numpunct<char>
{
protected:
virtual char do_decimal_point() const {return ',';}
virtual char do_thousands_sep() const {return '.';}
virtual std::string do_grouping() const {return std::string("\2\3");}
};
int main()
{
std::ostringstream os;
os.imbue(std::locale(os.getloc(), new my_punct));
os.precision(2);
fixed(os);
double x = 123456789.12;
os << x;
std::string s = os.str();
std::cout << s << '\n';
}
通常,系统缺省的local设置下,输出的都是不带逗号的,但需要防止使用了std::ostringstream的代码位于动态库中时,
调用动态库的主程序可能会修改local设置,就导致了我之前碰到的问题。