我想从csv文件中提取数据,但我必须先获取表格的行数和列数。
到目前为止我的内容如下:
std::ifstream myfile(filename); // filename is a string and passed in by the constructor
if (myfile.is_open())
{
// First step: Get number of rows and columns of the matrix to initialize it.
// We have to close and re-open the file each time we want to work with it.
int rows = getRows(myfile);
std::ifstream myfile1(filename);
int columns = getColumns(myfile1);
if (rows == columns) // Matrix has to be quadratic.
{
std::ifstream myfile2(filename);
abwicklungsdreieck.set_Matrix(QuantLib::Matrix(rows, columns, 0)); // abwicklungsdreieck is initialised before
//...
}
else
{
std::cout << "\nNumber of rows has to equal number of columns.";
}
}
// [...]
int getRows(std::ifstream &myfile)
{
std::string line;
int rows = 0;
while (std::getline(myfile, line)) // While-loop simply counts rows.
{
rows++;
}
myfile.close();
return rows - 1;
}
int getColumns(std::ifstream &myfile)
{
std::string line;
char delimiter = ';';
size_t pos = 0;
int columns = 0;
while (std::getline(myfile, line) && columns == 0) // Consider first line in the .csv file.
{
line = line + ";";
while ((pos = line.find(delimiter)) != std::string::npos) // Counts columns.
{
line.erase(0, pos + 1);
columns++;
}
}
myfile.close();
return columns - 1;
}
此代码正常运行。但是,我必须打开文件三次,我不喜欢。有没有办法逃避这个?
我正在考虑在getRows()和getColumns()中使用临时文件,但复制流是不可能的,因为我最近学到的东西并没有意义。
那么,还有另一种方法吗?或者我可以例如逃避getline()和line.erase()方法吗?
答案 0 :(得分:0)
您可以逐行读取文件,将每行转换为流,然后读取流上的列:
std::ifstream myfile(filename);
if(!myfile) return 0;
std::string line;
while(std::getline(myfile, line))
{
std::stringstream ss(line);
std::string column;
while(std::getline(ss, column, ';'))
{
cout << column;
}
cout << "\n";
}
getline(myfile, line)
会将每一行复制到line
。
将行转换为ss
流。
getline(ss, column, ';')
会打破列中的行。
使用std::stoi
将字符串转换为整数。
如果您的矩阵基于std::vector
,则可以一次增加一行向量,因此您无需提前知道大小。
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
void readfile(const std::string &filename)
{
std::vector<std::vector<int>> matrix;
std::ifstream myfile(filename);
if(!myfile) return;
std::string buf;
while(std::getline(myfile, buf))
{
int maxrow = matrix.size();
std::stringstream ss(buf);
matrix.resize(maxrow + 1);
cout << "break in to columns:" << buf << "\n";
while(std::getline(ss, buf, ';'))
{
try {
int num = std::stoi(buf);
matrix[maxrow].push_back(num);
}
catch(...) { }
}
}
for(auto &row : matrix) {
for(auto col : row)
cout << col << "|";
cout << "\n";
}
}