【问题标题】:Reading only float values from text file仅从文本文件中读取浮点值
【发布时间】:2018-01-19 11:39:19
【问题描述】:

我有一个文本格式的数据文件。它有 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 

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

【问题讨论】:

  • 如果你知道它们是哪些行,你可以很容易地跳过非浮动行;您可以在循环中添加一个条件来检查您是否在该行。
  • 我将 2 列读取为 2 个字符串,然后尝试转换。好吧,更准确地说,我不会使用涉及更改列的数据类型的数据格式,但如果我无法更改,那么我会阅读并发布流程。

标签: c++ arrays filestreams


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    类似这样的:

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

    现在您已经解决了更高抽象级别的问题,您所要做的就是implement something like parseimplement something like is_double(分而治之)。

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

    【讨论】:

      【解决方案3】:

      我会使用这样的算法:

      对于文件中的每一行:

      1. 用空格分割字符串
      2. 对于此拆分的每个结果:
        1. 使用正则表达式“^\d+(\.\d+)?$”的马赫特
        2. 如果字符串匹配正则表达式,则转换为浮点数并保存在结果数组中

      【讨论】:

      • 您的正则表达式没有考虑语言环境。考虑一个使用, 而不是. 的系统。
      • OPs 文件似乎只包含. 作为十进制符号。如果需要,我认为将\. 更改为, 是微不足道的。本地化似乎也不是这个问题的主题。
      【解决方案4】:

      使用 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2020-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        • 2017-06-28
        相关资源
        最近更新 更多