Ale*_*sse 1 c c++ csv file-io matlab
我想知道是否有人可以帮助我尝试构建一个程序,以从csv文件读取大小未知的浮点大数据块。我已经在MATLAB中编写了此代码,但希望对其进行编译和分发,因此转向c ++。
我只是学习并尝试阅读以开始
7,5,1989
2,4,2312
Run Code Online (Sandbox Code Playgroud)
从文本文件。
到目前为止的代码。
// 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;
}
Run Code Online (Sandbox Code Playgroud)
我使用的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,:);
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏。亚历克斯
很明显,我只会使用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";
}
}
Run Code Online (Sandbox Code Playgroud)
给定文件的简单结构,实际上可以简化逻辑:如果不自动读取分隔符,则可以将每一行视为一系列值,而不是单独读取值。由于逗号不会被自动读取,因此在为内部行创建字符串流之前,逗号将被替换为空格。相应的代码变为
#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";
}
}
Run Code Online (Sandbox Code Playgroud)
这是发生了什么:
values定义为的向量的向量double。没有什么可以保证不同的行具有相同的大小,但是一旦读取文件就很难检查。std::ifstream被定义并与文件初始化。构造后可能值得检查文件,以查看是否可以将其打开以进行读取(if (!fin) { std::cout << "failed to open...\n";)。std::getline()将行读入即可读取这些行std::string。如果std::getline()失败,则无法读取另一行,转换结束。line被读取,所有的逗号之间用空格代替。line构成用于读取行的字符串流。原始代码重用了std::istringstream在循环外部声明的a ,以节省始终构造流的成本。由于流在行结束时变坏,因此首先需要对其进行in.clear()ed设置in.str(line)。std::istream_iterator<double>后者仅从构造它的流中读取一个值。给定的迭代器in是序列的开始,默认构造的迭代器是序列的结束。std::vector<double>代表行的临时项。之后的所有事情都只是使用C ++ 11功能(基于范围的for和具有auto明码推导类型的变量)简单地打印生成的矩阵的内容。