gpt4 book ai didi

c++ - 如何为小数点分隔符和位数调整 std::stod(字符串加倍)

转载 作者:可可西里 更新时间:2023-11-01 18:25:44 32 4
gpt4 key购买 nike

有没有办法调整 std::stod() 以增加(字符串到 double )转换中的小数位数并强制它使用美国语言环境?

我有一个可以在控制台或图形用户界面模式下运行的 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();
}

在这个应用程序中,我有一个 string to double 方法,它包装了新的 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;
}

奇怪的是,在控制台模式下,字符串到 double 转换需要一个以点作为小数点分隔符的字符串,而在 gui 模式下,它需要一个带逗号的字符串。此外,因为我之前使用的是 istringstream:

istringstream totalSString( valueAsString );
totalSString >> valueAsDouble;

我注意到 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;
}
}

我得到了这些结果:

“控制台”模式:

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() 的行为!

最佳答案

std::stod 是根据 std::strtod 定义的,它继承自 C 标准库。 C 函数 strtod 在 C 语言环境下工作,可通过 setlocale header 中的 <locale.h> 函数访问。

在 C++ 中,C 语言环境仍然可以通过 std::setlocale header 中的 <clocale> 函数访问,并且它确实会影响 std::strtodstd::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();
}

输出:

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

关于c++ - 如何为小数点分隔符和位数调整 std::stod(字符串加倍),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12316972/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com