2016-11-15 51 views
0

我最近有一个转换十进制字符串的错误,例如"10.057",至double。问题出在全局应用程序语言环境,使用boost::lexical_cast以及某些欧洲语言环境使用小数点的,这一事实。scanf,printf和boost :: lexical_cast从根本上是不安全的吗?

scanf,printf和这个家族中的其他功能都有同样的问题。

我很想听听其他人如何处理这个问题。

回答

0

scanf,printf,boost::lexical_cast和相关函数的行为取决于全局应用程序语言环境。因此它们在输入参数方面是非确定性的。我看过如下代码:

std::setlocale(LC_ALL, "C"); 
scanf(...); 

但是,这并不保证能够在多线程环境中工作。

解决方案是使用允许用户明确指定区域设置的函数和类型。

iostream流对象允许用户指定区域设置作为参数,这将产生确定性结果。

std::istringstream istr("10.057"); 
istr.imbue(std::locale::classic()); 

double val; 
istr >> val; 

同样,boost::format允许用户指定区域设置作为参数。

using boost::format; 
std::string s = str(format("%lf", std::locale::classic()) % 10.057); 

又见从以前stackoverflow question讨论。