1

我有一个文件,其中包含如下所示的数字行:

1.000000-5 2.436700+0 2.530000-2 2.436700+0 5.000000-2 2.436700+0
1.000000+1 2.436700+0 1.000000+2 2.433800+0 1.000000+3 2.433800+0

我需要用 C++ 阅读这个来获取数字

1.0E-5 2.4367E0 2.53E-2 2.4367E0 5.0E-2 2.4367E0
1.0E1 2.4367E0 1.0E2 2.4338E0 1.0E3 2.4338E0

挑战在于E文件的数量没有;表示E指数符号。

我怎样才能将这样的内容读入浮点数?它需要非常高效,因为我必须为每个文件读取数十万或数百万次。

关于如何实现这一点的任何建议?

4

4 回答 4

3

你应该写一个解析器。一个简单的实现是:

#include <iostream>
#include <sstream>
#include <vector>

int main() {

    // Signed data set
    std::istringstream input(
        "+1.000000-5 -2.436700+0 +2.530000-2 -2.436700+0 +5.000000-2 -2.436700+0\n"
        "+1.000000+1 -2.436700+0 +1.000000+2 -2.433800+0 +1.000000+3 -2.433800+0");

    std::vector<double> result;

    std::string in;
    while(input >> in) {
        auto e = in.find_last_of("+-");
        if(0 < e && e != std::string::npos) {
            in.replace(e, 1, std::string("E") + in[e]); // this might get a optimization
        }
        std::istringstream number(in);
        double d;
        number >> d;
        result.push_back(d);
    }
    for(auto d: result) std::cout << std::fixed << d << std::endl;
    return 0;
}
于 2013-08-29T21:31:25.787 回答
3

我只需在每个 - 或 + 之前添加 E 并在其上使用atofstrtof

如果这对您来说还不够快,请查看您最喜欢的实现atof(我无法通过简单的搜索找到一个,但应该不会太难)并对其进行更改,使其不查找 E , 但仅用于 - 或 +。

于 2013-08-29T20:40:14.213 回答
0

这是我刚刚快速破解的东西,您需要测试它是否适用于您的所有情况:

ifstream file;
file.open("f:\\stackoverflow\\fortranfloat\\fortranfloats.txt");

string line;
if (file.is_open())
{
    while (file.good())
    {
        getline(file, line);
        for (int i = 0; i < line.length(); i++)
        {
            int j = 0;
            char buf[10];
            while (i < line.length() && line[i] != ' ')
            {
                if (line[i] == '-' || line[i] == '+')
                    buf[j++] = 'e';

                buf[j++] = line[i++];
            }
            float number = atof(buf);
            cout << "Number: " << number << endl;
        }
    }
    file.close();
}
else
{
    cout << "Failed to open file" << endl;
}
于 2013-08-29T21:01:02.137 回答
0

将字符串扫描到 + 或 -(或空格)字符并存储。将 + 或 - 替换为 null 并将字符串传递给 atof 以获取第一部分。然后,如果您在指数中有 + 或 - 扫描。一旦你在 int 或 double 中有它,使用value * pow(10.0, exponent). 或者您可以使用 strtod 并避免空修改。

或者如前所述,修改现有的 atof 实现。

于 2013-08-29T20:42:13.240 回答