0

我有一个文本格式的数据文件。它有 2 个列,第一个没有用,我可以忽略它,第二个是我需要的。coloum 在每一行都有不同的值,如字符串、浮点数等。对于某些计算,我只需要浮动这个 coloum 的成员。我按照这种方式,首先声明一个浮点数组并读取值并使用“>>”基本命令保存数组。

问题是当非浮动行出现时,读取功能会损坏。它将非浮点值读取为“0”并另存为。没关系,但之后将整个值读取为“0”,即使它是一个浮点数。

Datafile.txt(示例)

aa 1.1
bb 2.2
cc 3.0
dd somestring
ee 4.3
ff 4.9

代码(示例)

 do 
{
    dfile >> a >> dat[i]; 
    ofile << dat[i]<<endl;
    cout << dat[i]<<endl;
    i++;

}while(dfile.eof());

输出文件(示例)

1.1
2.2
3.0
0
0
0
..goes 

我想了两种方法来解决这个问题。第一个是跳过非浮动行。第二个是在一段时间内阅读行。因为浮点值按顺序列出。

4

4 回答 4

2

首先读取一个字符串,然后尝试转换为一个数字:

std::string maybeNumber;
while (dfile >> a >> maybeNumber)
{

    std::istringstream is(maybeNumber);
    float number = 0.0f;
    if (is >> number)
    {
        dat[i] = number;
        i++;
    }    
}

(您不想使用eof。每个人都认为他们想使用eof,但这几乎总是不是他们需要的。有关详细信息,请参阅此问题。)

于 2018-01-19T11:53:15.163 回答
1

没关系,但之后将整个值读取为“0”,即使它是一个浮点数。

您还没有显示完整的代码,但这听起来像输入流在第一个不可解析的浮点数之后处于错误状态,因此它根本停止读取任何内容。

至于问题的解决方案,将每一行读为 a std::string,然后将一行拆分为 a std::vector<std::string>。如果向量不包含两个元素,或者第二个元素不是 a double,则什么也不做,否则处理该行。

像这样的东西:

std::string line;
while (std::getline(dfile, line))
{
    auto const elements = parse(line);
    if (size(elements) == 2 && is_double(elements[1]))
    {
        // process
    }
}

现在您已经在更高的抽象级别上解决了问题,您所要做的就是实现类似的东西parse实现类似的东西is_double(分而治之)。

另请注意,默认的 C++ 浮点类型是double而不是float. 如有疑问,请使用double.

于 2018-01-19T11:55:30.483 回答
1

我会使用这样的算法:

对于文件中的每一行:

  1. 用空格分割字符串
  2. 对于此拆分的每个结果:
    1. 带有正则表达式的马赫特 "^\d+(\.\d+)?$"
    2. 如果字符串与正则表达式匹配,则转换为浮点数并保存在结果数组中
于 2018-01-19T11:56:01.450 回答
1

使用getlineregex_token_iterator

#include <regex>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<float> v;
    std::regex reg("-?\\d+(\\.\\d+)?");
    const char* filename="myfile.txt";

    std::ifstream ifs(filename,std::ios::binary);

    for(std::string s;std::getline(ifs,s);)
       for(std::sregex_token_iterator rgi(s.begin(),s.end(),reg);rgi!=std::sregex_token_iterator();++rgi)
         v.push_back(std::stof(rgi->str());

    std::copy(v.begin(),v.end(),std::ostream_iterator<float>(std::cout," ");
    return 0;
}
于 2018-08-04T13:38:02.437 回答