2016-11-15 14 views
0

最近、10進文字列を変換するバグがありました。 "10.057"からdoubleへと変化する。問題は、グローバルアプリケーションロケール、boost::lexical_castの使用、および一部のヨーロッパのロケールでは小数点のために,を使用していたという事実が原因でした。scanf、printf、boost :: lexical_castは基本的に危険ですか?

scanfprintfなど、このファミリの他の機能にも同じ問題があります。

他の人がこの問題にどのように対処しているのか聞いてみたいと思います。

答えて

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からの説明も参照してください。

関連する問題