【发布时间】:2021-01-06 04:35:41
【问题描述】:
我有一个 C++ 代码可以从 csv 文件加载二维向量。在这里,output.csv 文件的数据为 65 x 74496。在此代码中,我将行和列的大小固定为 65 和 74496。但是,将来可以根据数据更改行数和列数。你知道一种从 csv 文件中自动选择行数和列数的方法吗?谢谢!
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
const std::string csvFileName{ "output.csv" };
constexpr size_t NumberOfRows = 65U; // I want to decide this number from csv file automatically
constexpr size_t NumberOfColumns = 74496U; // I want to decide this number from csv file automatically
int main() {
// writeTestFile();
// Our data
std::vector<std::vector<std::string>> data(NumberOfRows, std::vector<std::string>(NumberOfColumns));
// Open file and check, if it is open
if (std::ifstream testFileStream{ csvFileName }){//; testFileStream) {
size_t row{};
std::string line{};
line.resize(1'000'000U);
// Read all lines/rows in a loop
while (testFileStream >> line) {
size_t columnIndex{};
std::vector<std::string> columns(NumberOfColumns);
// split strings
std::istringstream iss{ line };
for (std::string part{}; std::getline(iss, part, ','); columns[columnIndex++] = std::move(part))
;
// Add all column values
data[row++] = std::move(columns);
}
}
else std::cerr << "\n\nError: Could not open file: " << csvFileName << "\n\n";
std::cout << "Hello World!\n";
std::cout << data[1][1] << std::endl;
return 0;
}
【问题讨论】:
-
如果您不需要预先分配内存,则表示您的
csv line,我们称它为Data,逐行读取并从每一行制作Data,将数据添加到@ 987654328@ -
行数=行,一行中的值数=列
-
line.resize(1'000'000U);将被testFileStream >> line撤消。它可能会保留分配的数百万字节,否则会浪费大量时间。也许reserve会更合适。 -
testFileStream >> line不会读取整行,除非该行是单个空格分隔的标记。您可能在此处以及解析逗号时需要getline。 -
注意:
std::vector::push_back或std::vector::emplace_back解决了您所询问的问题。从它们开始,然后在玩预分配之前测试结果是否足够快。预分配减少了内存分配的次数,但需要您读取文件两次。重复的文件 IO 可能比vector调整大小更昂贵。