【问题标题】:Deciding 2d vector size automatically from csv file从 csv 文件自动确定 2d 矢量大小
【发布时间】: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 &gt;&gt; line 撤消。它可能会保留分配的数百万字节,否则会浪费大量时间。也许reserve 会更合适。
  • testFileStream &gt;&gt; line 不会读取整行,除非该行是单个空格分隔的标记。您可能在此处以及解析逗号时需要getline
  • 注意:std::vector::push_backstd::vector::emplace_back 解决了您所询问的问题。从它们开始,然后在玩预分配之前测试结果是否足够快。预分配减少了内存分配的次数,但需要您读取文件两次。重复的文件 IO 可能比 vector 调整大小更昂贵。

标签: c++ csv vector


【解决方案1】:

this answer

这是使用动态数组大小的修改版本。

sam源文件46MB,耗时1399ms。

正如多次写的:请在您的编译器中启用 C++ 17!!!

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

const std::string csvFileName{ "r:\\test.csv" };
constexpr size_t NumberOfRows = 65U;
constexpr size_t NumberOfColumns = 74496U;


void writeTestFile() {
    // Open file and check, if it could be opened
    if (std::ofstream testFileStream{ csvFileName }; testFileStream) {

        // Write all columns
        for (size_t row{}; row < NumberOfRows; ++row) {

            //  Special handling for separator. No comma at the end
            bool writeCommaFirst{ false };

            // For all columns
            for (size_t col{}; col < NumberOfColumns; ++col) {

                // // Create some test string
                std::string temp = "R" + std::to_string(row) + "C" + std::to_string(col);

                // Write data
                testFileStream << (writeCommaFirst ? "," : "") << temp;
                writeCommaFirst = true;
            }
            testFileStream << '\n';
        }
    }
    else std::cerr << "\n\nError. Could not write file" << csvFileName << "\n\n";
}

int main() {
    // writeTestFile();

    // Our data
    std::vector<std::vector<std::string>> data{};

    // Open file and check, if it is open
    if (std::ifstream testFileStream{ csvFileName }; testFileStream) {

        std::string line{};
        line.reserve(1'000'000U);

        // Read all lines/rows in a loop
        while (std::getline(testFileStream, line)) {


            size_t columnIndex{};
            std::vector<std::string> columns{};

            // split strings
            std::istringstream iss{ line };
            for (std::string part{}; std::getline(iss, part, ','); columns.emplace_back(std::move(part)))
                ;
            // Add all column values
            data.emplace_back(std::move(columns));
        }
    }
    else std::cerr << "\n\nError: Could not open file: " << csvFileName << "\n\n";
    return 0;
}

【讨论】:

  • 嗨,阿明,感谢您的帮助。我们可以从 csv 文件中获取 NumberOfRows 和 NumberOfColumns 吗?
  • 我编辑了代码。它现在是完全动态的。可以有任意多的行和列。甚至不同行中的不同列数也是可能的。读取后的行数是 data.size() 和列数,例如第 0 行是 data[0].size();
  • Armin Montigny,感谢它运行良好!你真聪明!
  • 嗨,Armin Montigny,我制作了一个二维向量,vector > EEG_data;我想将数据(读取 csv 文件的结果)复制到 EEG_data 作为两倍。 for (int i = 0; i
  • 此代码不起作用。 EEG_data[i][j] = (double)data[i][j] 你知道怎么解决吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2019-11-18
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
相关资源
最近更新 更多