C++におけるcsvファイル⇔二次元配列の変換


はじめに

自分用の覚書です。二次元配列をcsvに読み書きする方法。
まともな記事は「c++ csv」で検索すれば山程見つかるのでそちらを参照されてください。

環境

割愛
MacOS
C++14,17

読み取り(csv ➡ 二次元配列)

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

// input を delimiter で分割する関数
std::vector<std::string> split(std::string &input, char delimiter) {
  std::istringstream stream(input);
  std::string field;
  std::vector<std::string> result;
  while (getline(stream, field, delimiter)) result.push_back(field);
  return result;
}

// csvファイルの読み取り
void read() {
  std::string path = "/Users/usr/.../input.csv"; // 読み取り元
  std::ifstream ifs(path);                       // 読み取り用ストリーム
  std::vector<std::vector<int> > data;           // 読み取ったデータの格納場所
  if (ifs) {
    std::string line;

    // 一行目がラベルの場合
    // getline(ifs, line);
    // std::vector<std::string> strvec = split(line, ',');

    while (getline(ifs, line)) {
      std::vector<int> datvec;
      std::vector<std::string> strvec = split(line, ',');
      for (auto &&s : strvec) datvec.push_back(std::stoi(s)); // セルの文字列を数値に変換
      data.push_back(datvec);
    }
  }
}

書き出し(二次元配列 ➡ csv)

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

// csvファイルの書き出し
void write() {
  std::string path = "/Users/usr/.../output.csv";                   // 書き出し先
  std::ofstream ofs(path);                                          // 書き出し用ストリーム
  std::vector<std::vector<int> > data(10, std::vector<int>(10, 2)); // csvにしたいデータ
  if (ofs) {
    for (size_t i = 0; i < data.size(); i++) {
      for (size_t j = 0; j < data[i].size(); j++) ofs << data[i][j] << ",";
      ofs << std::endl;
    }
  }
}

参考文献

おわりに

pythonだとsplitがあるので楽です。
read()で作られるdataはアクセスが悪いのでそのまま使うのは少しモヤります。