有没有办法调整std :: stod()以增加(字符串到双精度)转换中的小数位数并强制它使用美国语言环境?
我有一个可以在控制台或gui模式下运行的Qt应用程序:
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();
}
在这个应用程序中,我有一个包装新C ++ 11 stod的字符串to double方法:
double s2d ( const string &string_h) const {
try {
return stod(string_h);
} catch (...) {
if (string_h == "") return 0;
else {
cout << "error!" << endl;
}
}
return 0;
}
奇怪的是,在控制台模式下,字符串到双转换需要一个带点作为十进制分隔符的字符串,在gui模式下它需要一个带逗号的字符串。 此外,正如我以前使用istringstream:
istringstream totalSString( valueAsString );
totalSString >> valueAsDouble;
我注意到stod会将生成的double缩减为只有3位十进制数,远远小于istringstream。
那么有没有办法增加十进制数字并强制std :: stod使用美国语言环境进行转换?
谢谢: - )
EDITED :
如果我尝试这个脚本:
// 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;
}
}
我得到了这些结果:
“console”模式:
Conversion passed: 123.1234567890 - 123.123
Conversion passed: 123.1234 - 123.123
Conversion passed: 123,1234567890 - 123
Conversion passed: 123,1234 - 123
“gui”模式:
Conversion passed: 123.1234567890 - 123
Conversion passed: 123.1234 - 123
Conversion passed: 123,1234567890 - 123.123
Conversion passed: 123,1234 - 123.123
显然有一些影响stod()行为的东西!
答案 0 :(得分:5)
std::stod
及其亲属旨在提供简单,从字符串到数字类型的快速转换。 (完全披露:这是我的设计)所以,不,没有区域设置;所见即所得。
答案 1 :(得分:3)
std::stod
是将std::string
转换为double的通用方法。如果你想要更具体的东西,你应该自己实现它。
例如:
double my_stod(const std::string &valueAsString) {
istringstream totalSString( valueAsString );
double valueAsDouble;
// maybe use some manipulators
totalSString >> valueAsDouble;
if(!totalSString)
throw std::runtime_error("Error converting to double");
return valueAsDouble;
}
答案 2 :(得分:3)
std::stod
是根据std::strtod
定义的,它是从C标准库继承的。 C函数strtod
按照C语言环境工作,可通过setlocale
头中的<locale.h>
函数访问。
在C ++中,仍可以通过std::setlocale
标头中的<clocale>
函数访问C语言环境,并且确实会影响std::strtod
和std::stod
。
Qt的QApplication
使用std::setlocale
来设置用户选择的语言环境。因此,每当在GUI Qt应用程序中使用C语言环境相关的函数时,您都将拥有语言环境相关的基数。
现在,要强制使用数字的特定语言环境,可以按以下方式使用std::setlocale
。但是请注意,由于C语言环境是线程全局状态,因此这可能会破坏多线程应用程序。下面的示例将程序的语言环境临时设置为LC_NUMERIC=C
,并在调用std::stod
之后恢复设置。
#include <iostream>
#include <clocale>
#include <vector>
#include <string>
void test()
{
for(auto s : {"123.1234567890",
"123.1234",
"123,1234567890",
"123,1234"})
{
// Save locale setting
const auto oldLocale=std::setlocale(LC_NUMERIC,nullptr);
// Force '.' as the radix point. If you comment this out,
// you'll get output similar to the OP's GUI mode sample
std::setlocale(LC_NUMERIC,"C");
try
{
const auto outd=std::stod(s);
std::cout << "Conversion succeeded: " << s << " => "
<< outd << '\n';
}
catch (...)
{
std::cout << "Conversion FAILED : " << s << " => ???\n";
}
// Restore locale setting
std::setlocale(LC_NUMERIC,oldLocale);
}
}
#include <QApplication>
int main(int argc, char** argv)
{
std::cout << "Test in normal console mode\n";
test();
QApplication app(argc, argv);
std::cout << "Test in GUI mode\n";
test();
}
输出:
Test in normal console mode
Conversion succeeded: 123.1234567890 => 123.123
Conversion succeeded: 123.1234 => 123.123
Conversion succeeded: 123,1234567890 => 123
Conversion succeeded: 123,1234 => 123
Test in GUI mode
Conversion succeeded: 123.1234567890 => 123.123
Conversion succeeded: 123.1234 => 123.123
Conversion succeeded: 123,1234567890 => 123
Conversion succeeded: 123,1234 => 123