ifstream的已删除副本构建器的替代方法
Alternative for deleted copy constrctor of ifstream
我想从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((方法吗?
您可以逐行读取文件,将每行转换为流,然后读取流上的列:
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";
}
}
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- 是否有一种方法可以始终通过值(制作副本)而不是在使用类成员函数时通过参考来传递
- 如何在我的源代码中找到所有发生的情况,其中std :: string被传递给方法作为副本而不是恒定引用
- ifstream的已删除副本构建器的替代方法
- 创建std :: vector减去一个元素的副本的最快方法
- C++方法返回自身副本时内存泄漏
- 将对象副本添加到容器的更好方法
- 按方法返回副本或引用
- 对字符串副本执行迭代器运算的更简单方法
- 在C ++ R3.0.2驱动程序中使用连接池连接到MongoDB副本集的正确方法是什么?
- 如何从方法返回std::vector,而不是每次都是副本
- 指针副本的虚方法不工作
- 从重写方法返回派生类,声明为返回基副本
- 从c++方法返回引用和副本