scanf,printf和boost :: lexical_cast从根本上说是不安全的吗?

时间:2016-11-15 23:13:14

标签: c++ printf locale scanf lexical-cast

我最近有一个转换十进制字符串的错误,例如"10.057"double。问题在于全局应用程序区域设置,boost::lexical_cast的使用以及一些欧洲区域设置使用,作为小数点的事实。

scanfprintf以及此系列中的其他功能也有同样的问题。

我很想知道别人如何处理这个问题。

1 个答案:

答案 0 :(得分:0)

scanfprintfboost::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的讨论。