Ant*_*llo 7 c++ qt locale type-conversion c++11
有没有办法调整std :: stod()以增加(字符串到双)转换中的小数位数并强制它使用美国语言环境?
我有一个Qt应用程序,可以在控制台或gui模式下运行:
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();
}
Run Code Online (Sandbox Code Playgroud)
在这个应用程序中,我有一个包含新C++ 11 stod的字符串到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;
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,在控制台模式下,字符串到双转换需要一个带点作为十进制分隔符的字符串,在gui模式下它需要一个带逗号的字符串.此外,正如我以前使用istringstream:
istringstream totalSString( valueAsString );
totalSString >> valueAsDouble;
Run Code Online (Sandbox Code Playgroud)
我注意到stod会将生成的double缩减为只有3位十进制数,远小于istringstream.
那么有没有办法增加十进制数字的数量并强制std :: stod使用美国语言环境进行转换?
谢谢 :-)
编辑:
如果我尝试这个脚本:
// 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了这些结果:
"控制台"模式:
Conversion passed: 123.1234567890 - 123.123
Conversion passed: 123.1234 - 123.123
Conversion passed: 123,1234567890 - 123
Conversion passed: 123,1234 - 123
Run Code Online (Sandbox Code Playgroud)
"gui"模式:
Conversion passed: 123.1234567890 - 123
Conversion passed: 123.1234 - 123
Conversion passed: 123,1234567890 - 123.123
Conversion passed: 123,1234 - 123.123
Run Code Online (Sandbox Code Playgroud)
显然有一些影响stod()行为的东西!
std::stod是根据 定义的std::strtod,它继承自 C 标准库。C 函数strtod根据 C 语言环境工作,可通过头文件中的setlocale函数访问<locale.h>。
在 C++ 中,C 语言环境仍然可以通过头文件中的std::setlocale函数访问<clocale>,它确实影响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 std::string 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.c_str());
}
}
#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();
}
Run Code Online (Sandbox Code Playgroud)
输出:
#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 std::string 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.c_str());
}
}
#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();
}
Run Code Online (Sandbox Code Playgroud)
std::stod它的亲属旨在提供从字符串到数字类型的简单快速转换.(完全披露:这是我的设计)所以,不,没有区域设置; 你所看到的就是你得到的.
| 归档时间: |
|
| 查看次数: |
7296 次 |
| 最近记录: |