- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
有没有办法调整 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::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();
}
输出:
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/
我正在使用Mapbox开发 map 应用程序。 我正在使用的方法使用Point(Double,Double) 获取类型不匹配要求:两次发现:两次? val lat = location
我想将 System.out 消息写入另一个 OutputStream,但我仍然想要标准输出。 我找到了类似问题的答案Copy and Redirecting System.err Stream :
我正在尝试为我正在处理的排序找到所有处理器的全局最小值和最大值。我正在尝试使用 MPI_Reduceall int rank, nproc; MPI_Comm_size(MPI_COMM_WORLD,
我想知道从一种可空类型转换为另一种“兼容”可空类型的最佳方式(从更安全和简洁的意义上说)是什么。 具体来说,从十进制转换?加倍?可以使用: public double? ConvertToNullab
我的一个表的文件大小(.MYD 文件)增加了大约 100%。如果我查看数据,就会发现过去几天的每日负载正常。是什么导致文件大小增加? myisamchk 根据用户的建议,我尝试了sudo myisam
我有一个 invoices 表。每张发票都有许多 invoice_items 和 transactions(或者,如果您愿意,也可以是“付款”)。对于每张发票,我想计算已支付金额(即其交易金额的总和)
我需要一个尽可能接近 0 的值。我需要能够除以这个值,但实际上它应该为 0。 Java 是否提供了一种简单的方法来生成仅设置最低有效位的 double ?还是必须自己计算? //编辑:一些背景信息,因
由于 Math.random ()(以及大多数伪随机数生成器,AFAIK)在 [0,1) 中生成数字: function randomInRange(min, max) { return Math
这应该很容易。相信我,我已经为此研究了几个小时。我的查询: SELECT not_piece.pid, part.name AS 'Part Name', SUM(qty_left) AS 'In S
我正在尝试传递类型为 vector > 的变量到函数 F(double ** mat, int m, int n) . F 函数来自另一个库,所以我无法更改它。有人可以给我一些提示吗?谢谢。 最佳答案
我正在尝试读取一个文件,读取它包含的字节数,然后将其四舍五入到最接近的 GB,然后将文件大小加倍。但是,有没有办法读取文件,然后将所有这些东西重新放入同一个文件中? 这是我目前所拥有的,但它创建了一个
我正在尝试传递类型为 vector > 的变量到函数 F(double ** mat, int m, int n) . F 函数来自另一个库,所以我无法更改它。有人可以给我一些提示吗?谢谢。 最佳答案
我想对超大 (200+ MB) Sqlite 文件进行一些测试。我有一些相对较小的文件 (10MB),但我想测试更大的文件。 有没有什么快速的方法/工具可以通过复制表中的数据来增加这些 Sqlite
我有一个 64 位数字,写成两个 32 位未签名的整数:unsigned int[2]。 unsigned int[0] 是 MSB,unsigned int[1] 是 LSB。我如何将它转换为 do
我需要将数量的值传递给库进行评估。 boost units library在 SI 中采用双倍值,因此 boost 单位库在确保该要求方面非常有吸引力。但是,我应该如何将数量转换为双倍值?文档和示例似
如何向 ksoap2 请求添加双重属性? request.addProperty("doubleProperty", 1.0); 网络上没有明确的答案。 最佳答案 为了将 double 值作为请求参数
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 7 年前。 Improve this qu
我正在尝试从 AngularJS 用 Swing 编写的 REST API 生成 .bin 文件。以下是代码。 var options = { url: 'http://example.com/i
我对这段代码中的特定值集有疑问。 double inputs[] = {0, -546543, 99015, 6750, 825, 2725, 70475, 50950, 42200, 675
我在 ruby on rails 应用程序中尝试为密码生成盐时遇到了 SecureRandom#hex 方法。为什么它会加倍长度参数/坚持返回的字符串长度是偶数? 最佳答案 该方法生成一个 n 字
我是一名优秀的程序员,十分优秀!