gpt4 book ai didi

c++程序,用于将具有恒定(但未知)列数的未知大小的csv文件(仅填充 float )读取到数组中

转载 作者:太空宇宙 更新时间:2023-11-04 00:50:59 26 4
gpt4 key购买 nike

想知道是否有人可以帮助我尝试构建一个程序,该程序从 csv 文件中读取大小未知的 float 大数据 block 。我已经在 MATLAB 中编写了这个,但想编译和分发它,所以转向 c++。

我只是在学习并尝试阅读本文以开始

7,5,1989
2,4,2312

来自文本文件。

到目前为止的代码。

// Read in CSV
//
// Alex Byasse

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stdlib.h>

int main() {

unsigned int number_of_lines = 0;
FILE *infile = fopen("textread.csv", "r");
int ch;
int c = 0;
bool tmp = true;
while (EOF != (ch=getc(infile))){
if(',' == ch){
++c;
}
if ('\n' == ch){
if (tmp){
int X = c;
tmp = false;
}
++number_of_lines;
}
}
fclose(infile);

std::ifstream file( "textread.csv" );

if(!file){
std:cerr << "Failed to open File\n";
return 1;
}

const int ROWS = X;
const int COLS = number_of_lines;
const int BUFFSIZE = 100;
int array[ROWS][COLS];
char buff[BUFFSIZE];
std::string line;
int col = 0;
int row = 0;
while( std::getline( file, line ) )
{
std::istringstream iss( line );
std::string result;
while( std::getline( iss, result, ',' ) )
{
array[row][col] = atoi( result.c_str() );
std::cout << result << std::endl;
std::cout << "column " << col << std::endl;
std::cout << "row " << row << std::endl;
col = col+1;
if (col == COLS){
std:cerr << "Went over number of columns " << COLS;
}
}
row = row+1;
if (row == ROWS){
std::cerr << "Went over length of ROWS " << ROWS;
}
col = 0;
}
return 0;
}

我使用的matlab代码是>>

fid = fopen(twoDM,'r');

s = textscan(fid,'%s','Delimiter','\n');
s = s{1};
s_e3t = s(strncmp('E3T',s,3));
s_e4q = s(strncmp('E4Q',s,3));
s_nd = s(strncmp('ND',s,2));

[~,cell_num_t,node1_t,node2_t,node3_t,mat] = strread([s_e3t{:}],'%s %u %u %u %u %u');
node4_t = node1_t;
e3t = [node1_t,node2_t,node3_t,node4_t];
[~,cell_num_q,node1_q,node2_q,node3_q,node_4_q,~] = strread([s_e4q{:}],'%s %u %u %u %u %u %u');
e4q = [node1_q,node2_q,node3_q,node_4_q];
[~,~,node_X,node_Y,~] = strread([s_nd{:}],'%s %u %f %f %f');

cell_id = [cell_num_t;cell_num_q];
[~,i] = sort(cell_id,1,'ascend');

cell_node = [e3t;e4q];
cell_node = cell_node(i,:);

感谢任何帮助。亚历克斯

最佳答案

显然,我会只使用 IOStreams。从 CSV 文件中读取同构数组或数组而不必费心使用任何引用是非常简单的:

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

std::istream& comma(std::istream& in)
{
if ((in >> std::ws).peek() != std::char_traits<char>::to_int_type(',')) {
in.setstate(std::ios_base::failbit);
}
return in.ignore();
}

int main()
{
std::vector<std::vector<double>> values;
std::istringstream in;
for (std::string line; std::getline(std::cin, line); )
{
in.clear();
in.str(line);
std::vector<double> tmp;
for (double value; in >> value; in >> comma) {
tmp.push_back(value);
}
values.push_back(tmp);
}

for (auto const& vec: values) {
for (auto val: vec) {
std::cout << val << ", ";
}
std::cout << "\n";
}
}

考虑到文件的简单结构,逻辑实际上可以简化:不是单独读取值,如果自动读取分隔符,则每一行都可以看作是一个值序列。由于不会自动读取逗号,因此在为内部行创建字符串流之前将逗号替换为空格。对应代码变为

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

int main()
{
std::vector<std::vector<double> > values;
std::ifstream fin("textread.csv");
for (std::string line; std::getline(fin, line); )
{
std::replace(line.begin(), line.end(), ',', ' ');
std::istringstream in(line);
values.push_back(
std::vector<double>(std::istream_iterator<double>(in),
std::istream_iterator<double>()));
}

for (std::vector<std::vector<double> >::const_iterator
it(values.begin()), end(values.end()); it != end; ++it) {
std::copy(it->begin(), it->end(),
std::ostream_iterator<double>(std::cout, ", "));
std::cout << "\n";
}
}

这是发生了什么:

  1. 目的地 values被定义为 vector 的 vector double .没有任何东西可以保证不同行的大小相同,但是在读取文件后检查起来很简单。
  2. std::ifstream用文件定义和初始化。可能值得在构建后检查文件,看它是否可以打开以供阅读 (if (!fin) { std::cout << "failed to open...\n";)。
  3. 文件一次处理一行。使用 std::getline() 简单地读取这些行将它们读入 std::string .当std::getline()失败它无法读取另一行并且转换结束。
  4. 一旦line被读取,所有逗号被空格替换。
  5. 来自如此修改的line构造了一个用于读取该行的字符串流。原始代码重用了 std::istringstream这是在循环外声明的,以节省一直构建流的成本。由于当线路完成时流变坏,它首先需要是 in.clear()在其内容设置为 in.str(line) 之前编辑.
  6. 各个值使用 std::istream_iterator<double> 进行迭代它只是从构造它的流中读取一个值。给定的迭代器 in是序列的开始,默认构造的迭代器是序列的结束。
  7. 迭代器产生的值序列用于立即构建临时 std::vector<double>代表一行。
  8. 临时 vector 被推到目标数组的末尾。

之后的一切都是使用 C++11 功能简单地打印生成的矩阵的内容(基于范围的 for 和变量,具有 auto 自动推导的类型)。

关于c++程序,用于将具有恒定(但未知)列数的未知大小的csv文件(仅填充 float )读取到数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18818777/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com