C ++ Parse行可变长度的双精度数

时间:2012-07-23 21:31:20

标签: c++ string-parsing

我试图逐行读取文件,根据空格解析它并将其放入一个名为input的向量中。但是,我不能做一个cin>> x1>> x2>> x3 ...因为该行没有一定数量的术语。以下是我的想法,但可能是错误的。

vector <double> input;
fstream inputFile("../Sphere.in", fstream::in);
inputFile.open("../Sphere.in", fstream::in);

while (inputFile.good())
{
    getline(inputFile, line);

然后这里的内容表示输入[i]

中的每个空格
 }

我是C ++的新手,非常感谢有人可以帮助我。

谢谢,

约翰

2 个答案:

答案 0 :(得分:4)

如果您只想要一个平面的双打集合:

#include <vector>
#include <istream>     //  for operator>>
#include <fstream>     //  for std::ifstream

std::vector<double> v;
for (double d; inputFile >> d; ) { v.push_back(d); }

或更简单:

// includes as above
#include <iterator>

std::vector<double> v((std::istream_iterator<double>(inputFile)),
                      std::istream_iterator<double>());

如果您想要每行的容器:

// includes as above
#include <string>
#include <sstream>

std::vector<std::vector<double>> v;

for (std::string line; std::getline(inputFile, line); )
{
    std::istringstream iss(line);
    v.emplace_back(std::istream_iterator<double>(iss),
                   std::istream_iterator<double>());
}

在逐行方法中,您还可以检查是否已成功到达输入字符串的末尾,或者是否被无效输入停止并发出诊断信息。如果要将错误检查发送到极端,可以从流中提取单个字符串并将其解析为double(使用std::strtod)并在发生故障时发出诊断信息,跳过不可解决的令牌:

// ...
#include <cstdlib>

for (std::string line; std::getline(inputFile, line); )
{
    std::istringstream iss(line);
    v.emplace_back();

    for (std::string token; iss >> token; )
    {
        char * e;
        double const d = std::strtod(token.c_str(), &e);
        if (*e != '\0') { /* error! skip this token */ continue; }
        v.back().emplace_back(d);
    }
}

答案 1 :(得分:1)

while (inputFile.good())是错误的,因为它只在读取失败后评估为false 。如果没有循环内的额外检查,最后一次迭代将对无效输入起作用。正确的,惯用的方法是将读入循环的条件:

while (getline(inputFile, line)) { ... }

这样,只有在getline成功时才进入循环。现在你可以从line构造一个字符串流,并从那里读取双精度数,使用类似的方法读取内部循环条件:

while (getline(inputFile, line)) {
    istringstream iss(line);
    double d;
    while (iss >> d) input.push_back(d);
}