如何在C/C++中读取未知维度的数据文件

Sim*_*ker 3 c c++ file

我有一个数据文件,其中包含行/列形式的数据.我想用一种方法将这些数据读入C或C++中的2D数组(以较容易的方式)但我不知道在开始读取之前文件可能有多少行或列.

在文件的顶部是一个注释行,给出一系列与每列保持的数字相关的数字.每一行都在一个时间点保存每个数字的数据,因此一个示例数据文件(一个小的 - 我正在使用的数据更大!)可能是这样的:

# 1 4 6 28
21.2 492.1 58201.5 586.2
182.4 1284.2 12059. 28195.2
.....
Run Code Online (Sandbox Code Playgroud)

我目前正在使用Python来读取数据,使用numpy.loadtxt它可以方便地以行/列的形式分割数据,无论数据数组大小如何,但这变得非常慢.我希望能够在C或C++中可靠地完成这项工作.

我可以看到一些选择:

  1. 使用我的提取程序中的维度添加标题标记

    # 1 4 6 28
    # xdim, ydim
    21.2 492.1 58201.5 586.2
    182.4 1284.2 12059. 28195.2
    .....
    
    Run Code Online (Sandbox Code Playgroud)

    但这需要重写我使用提取数据的提取程序和程序,这是非常密集的.

  2. 将数据存储在数据库文件中,例如.MySQL,SQLite等.然后可以按需提取数据.这可能是开发过程中的一个要求,因此无论如何都可能是好的.

  3. 使用Python读入数据并包装C代码以进行分析.这在短期内可能是最简单的.

  4. 在linux上使用wc查找标题中的行数和单词数以查找维度.

    echo $((`cat FILE | wc -l` - 1)) # get number of rows (-1 for header line)
    echo $((`cat FILE | head -n 1 | wc -w` - 1)) # get number of columns (-1 for '#' character)
    
    Run Code Online (Sandbox Code Playgroud)
  5. 使用C/C++代码

这个问题主要与第5点有关 - 如果在C/C++中有一种简单可靠的方法.否则任何其他建议都会受到欢迎

谢谢

Man*_*uel 13

创建表作为向量的向量:

std::vector<std::vector<double> > table;
Run Code Online (Sandbox Code Playgroud)

在infinite(while(true))循环内:

读行:

std::string line;
std::getline(ifs, line);
Run Code Online (Sandbox Code Playgroud)

如果出现问题(可能是EOF),退出循环:

if(!ifs) 
    break;
Run Code Online (Sandbox Code Playgroud)

如果这是评论,请跳过该行:

if(line[0] == '#')
    continue;
Run Code Online (Sandbox Code Playgroud)

将行内容读入向量:

std::vector<double> row;
std::copy(std::istream_iterator<double>(ifs),
          std::istream_iterator<double>(),
          std::back_inserter(row));
Run Code Online (Sandbox Code Playgroud)

向表中添加行;

table.push_back(row);
Run Code Online (Sandbox Code Playgroud)

当你离开循环时,"table"包含数据:

  • table.size()是行数

  • table [i]是第i行

  • table [i] .size()是cols的数量.在我的行

  • table [i] [j]是第j列的元素.我的行


kni*_*666 10

怎么样:

  1. 加载文件.
  2. 计算行数和列数.
  3. 关闭文件.
  4. 分配所需的内存.
  5. 再次加载文件.
  6. 用数据填充数组.

我见过的每个.obj(3D模型文件)加载器都使用这种方法.:)

  • 您可以使用`fseek` /`fstream :: seekg`将光标重置为0而无需重新打开文件. (7认同)