is there a way to tweak std::stod() in order to increase the number of decimal digits in the (string to double) conversion and to force it to use the US locale?
I have a Qt application that can be run in both console or gui mode:
if (opt->getFlag( 'c' ) || opt->getFlag( "console" ) ){
ThreadManager modelMainThread;
modelMainThread.runFromConsole(inputFileName,scenarioName);
}
else {
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
Within this application I have a string to double method that wraps the new C++11 stod:
double s2d ( const string &string_h) const {
try {
return stod(string_h);
} catch (...) {
if (string_h == "") return 0;
else {
cout << "error!" << endl;
}
}
return 0;
}
Odd enough, while in the console mode the string to double conversion expects a string with dot as decimal separator, in the gui mode it instead expects a string with comma. Furthermore, as I was previously using istringstream:
istringstream totalSString( valueAsString );
totalSString >> valueAsDouble;
I noticed that stod truncates the resulting double to just 3 decimal digits, much less than istringstream.
So is there a way to increase the number of decimal digits and to force std::stod to use the US locale for the conversion ?
Thanks :-)
EDITED:
If I try this script:
// testing stod() ..
vector<string> numbers;
numbers.push_back("123.1234567890");
numbers.push_back("123.1234");
numbers.push_back("123,1234567890");
numbers.push_back("123,1234");
double outd;
for(uint i=0;i<numbers.size();i++){
try {
outd = stod(numbers[i]);
cout << "Conversion passed: " << numbers[i] << " - " << outd << endl;
} catch (...) {
cout << "Conversion DID NOT passed: " << numbers[i] << " - " <<endl;
}
}
I got these results:
"console" mode:
Conversion passed: 123.1234567890 - 123.123
Conversion passed: 123.1234 - 123.123
Conversion passed: 123,1234567890 - 123
Conversion passed: 123,1234 - 123
"gui" mode:
Conversion passed: 123.1234567890 - 123
Conversion passed: 123.1234 - 123
Conversion passed: 123,1234567890 - 123.123
Conversion passed: 123,1234 - 123.123
So clearly there is something influencing stod() behaviour !
std::stod
is a somehow generic way of converting astd::string
to a double. If you want something more specific, you should implement it yourself.For example:
std::stod
is defined in terms ofstd::strtod
, which is inherited from the C standard library. The C functionstrtod
works in terms of the C locale, accessible via thesetlocale
function from the<locale.h>
header.In C++, the C locale is still accessible via
std::setlocale
function in the<clocale>
header, and it does influence bothstd::strtod
andstd::stod
.Qt's
QApplication
usesstd::setlocale
to set the user-chosen locale. Thus whenever you use a C-locale-dependent function in a GUI Qt application, you'll have locale-dependent radix point.Now, to force a particular locale for numbers, you can use
std::setlocale
as follows. Note though, that this can break multithreaded apps, since C locale is a thread-global state. The example below will set program's locale temporarily toLC_NUMERIC=C
, and restore the setting after callingstd::stod
.Output:
std::stod
and its kin were designed to provide a simple, quick conversion from a string to a numeric type. (full disclosure: it's my design) So, no, no locales; what you see is what you get.