Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将奇怪字符串转换为双C++;_C++_Regex_String_Double_Data Conversion - Fatal编程技术网

C++ 将奇怪字符串转换为双C++;

C++ 将奇怪字符串转换为双C++;,c++,regex,string,double,data-conversion,C++,Regex,String,Double,Data Conversion,我需要将数据从文件转换为双精度文件,有时数据的格式为: 0.3387000000D+02 0.6067999217D-02 0.5095000000D+01 0.4530799416D-01 0.1159000000D+01 0.2028219738D+00 0.3258000000D+00 0.5039029350D+00 0.1027000000D+00 0.3834209505D+00 您将如何处理这里的D 这是用D代替E的科学记数法 我想在这里使用std::regex,但我希

我需要将数据从文件转换为双精度文件,有时数据的格式为:

0.3387000000D+02  0.6067999217D-02
0.5095000000D+01  0.4530799416D-01
0.1159000000D+01  0.2028219738D+00
0.3258000000D+00  0.5039029350D+00
0.1027000000D+00  0.3834209505D+00
您将如何处理这里的
D

这是用
D
代替
E
的科学记数法

我想在这里使用
std::regex
,但我希望有一个更优雅的策略

如下所示:

std::regex rr( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit]]+)?))?(d|D)((\\+|-)?)[[:digit:]]+)""?"); 标准:正则表达式rr((\+)?[:位:]+)(\。([:位]]+)?(d | d)((\+)?)[:位:]+)”;
D
替换为
E
,然后直接替换为:


你可以这样做

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>

double string2double(std::string s)
{
    // Find the index of scientific D
    int indexD = s.find('D');
    // separate the base from rest, start at 0 and go till index of D, without D
    std::string number = s.substr(0, indexD);
    //indexD+2 to ignore D and plus 
    std::string power = s.substr(indexD+2);
    
    // do conversion from string to number
    double rawNumber = std::stod(number);
    double powerNumber = std::stod(power);
    //test
    std::cout << rawNumber << std::endl;
    std::cout << powerNumber << std::endl;
    //return
    return rawNumber * std::pow(10, powerNumber);
}



int main()
{   

    std::string s = "0.3387000000D+02";
    std::cout << string2double(s) << std::endl;
    return 0;
}
#包括
#包括
#包括
#包括
#包括
双字符串双(标准::字符串s)
{
//查找科学数据索引
int indexD=s.find('D');
//将底部和其余部分分开,从0开始,直到索引为D,不带D
std::string number=s.substr(0,indexD);
//indexD+2忽略D和加号
std::字符串幂=s.substr(indexD+2);
//进行从字符串到数字的转换
double rawNumber=std::stod(编号);
双电源号=标准::stod(电源);
//试验

std::你能确定D和E的意思相同吗?你从哪里得到这些数据的?确认,它确实是E。这些数据来自量子化学软件包MOLPRO。我可以用E替换D,让标准转换函数处理其余的…@JohnFilleau Fortran使用D代替E。看,是的,这完全正确。MOLPRO是用谢谢你的链接!回复:“希望有一个更优雅的策略”--良好的直觉。正则表达式很少合适。我可以用一只手数一数我在StackOverflow上看到的关于正则表达式的问题的数量,其中正则表达式实际上是最好的解决方案。非常好!现在取决于程序的版本,只有有时字符串才有D。y也可以如果replace函数实际替换了任何内容,您可以修改代码以包含
if
语句?@zstreet,当然。@zstreet,完成了,第一个选项只有在找到
D
时才会替换,否则它什么也不做,但您有第二个选项。哦
std::replace
的第一个选项如果不好,则什么也不做
D
?我喜欢这样!谢谢!解析浮点文本有几个微妙的问题。这种蛮力代码大部分时间都可以工作,但它会导致许多边缘情况出错。例如,对于典型的64位双精度,最大指数是37。但是
.00001e40
是一个有效的有限值;它只是写得很有趣。
std::stod
可以处理这个问题;它产生的结果与std::stod(1.0e35)
相同。但是,如果您拆分指数,
std::pow(10,40)
将得到无穷大。将无穷大乘以任何非零值将得到无穷大,这就是此函数将返回的
.00001D40
。请注意,还有一个输入错误:
s.substr(indexD+2)
应该是
s.substr(indexD+1)
。该代码与
main
中的测试值一起工作,因为指数是
02
;如果指数是
12
,结果将是错误的。这里的寓意是:在处理浮点数学时不要相信你的直觉。你的直觉来自实数的经验;浮点数不是实数s、 而且你(和我的!)的直觉经常是错误的。谢谢你的评论,皮特!很高兴知道
bool isD(char c) { 
    return c == 'D'; 
}
std::string s = "0.3387000000D+02";
std::replace_if( s.begin(), s.end(), isD, 'E');
std::cout << std::stod(s);
33.87
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>

double string2double(std::string s)
{
    // Find the index of scientific D
    int indexD = s.find('D');
    // separate the base from rest, start at 0 and go till index of D, without D
    std::string number = s.substr(0, indexD);
    //indexD+2 to ignore D and plus 
    std::string power = s.substr(indexD+2);
    
    // do conversion from string to number
    double rawNumber = std::stod(number);
    double powerNumber = std::stod(power);
    //test
    std::cout << rawNumber << std::endl;
    std::cout << powerNumber << std::endl;
    //return
    return rawNumber * std::pow(10, powerNumber);
}



int main()
{   

    std::string s = "0.3387000000D+02";
    std::cout << string2double(s) << std::endl;
    return 0;
}