C++로 CSV 파일 읽기

Jinku Hu 2023년10월12일
C++로 CSV 파일 읽기

이 기사에서는 C++에서 CSV 파일을 읽는 방법에 대한 몇 가지 방법을 설명합니다.

std::getlinestd::istringstream을 사용하여 C++에서 CSV 파일 읽기

CSV 파일은 일반적으로 텍스트 파일 형식으로 알려져 있으며 각 행에서 값이 쉼표로 구분됩니다. 행을 데이터 레코드라고하며 각 레코드는 일반적으로 쉼표로 구분 된 둘 이상의 필드로 구성됩니다. CSV 형식은 대부분 테이블 형식 데이터를 저장하는 데 사용되므로 각 레코드에 동일한 수의 쉼표 구분 기호를 포함합니다. 그러나 실제로 여러 구현이 있기 때문에 예를 들어 쉼표로 구분 된 필드 사이에 공백이 있거나 필드 사이에 공백이 없을 수 있습니다. 다음 예에서는 사이에 공백이 없다고 가정합니다. 구역. 따라서 쉼표 사이의 모든 문자는 단일 데이터 단위로 간주됩니다.

먼저 파일 내용을 읽고std::string객체에 저장해야합니다. readFileIntoString함수는std::ostringstreamrdbuf를 사용하여 파일을 읽고string값을 호출자 함수에 반환합니다. 이전 단계가 성공적으로 완료되면string객체에서std::istringstream을 생성하고 각 행을 반복 할 수 있습니다. 이 반복에서는 라인의 각 필드를 추출하고std::vector에 저장하는 또 다른 루프를 넣습니다. 모든 라인 반복의 끝에서vectorstd::map에 저장하고 다음주기를 위해vector를 지 웁니다. std::map은 벡터의 벡터 또는 특정 시나리오에 최적 인 기타 사용자 정의 데이터 구조로 대체 될 수 있습니다.

#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::ostringstream;
using std::string;

string readFileIntoString(const string& path) {
  auto ss = ostringstream{};
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  ss << input_file.rdbuf();
  return ss.str();
}

int main() {
  string filename("grades.csv");
  string file_contents;
  std::map<int, std::vector<string>> csv_contents;
  char delimiter = ',';

  file_contents = readFileIntoString(filename);

  istringstream sstream(file_contents);
  std::vector<string> items;
  string record;

  int counter = 0;
  while (std::getline(sstream, record)) {
    istringstream line(record);
    while (std::getline(line, record, delimiter)) {
      items.push_back(record);
    }

    csv_contents[counter] = items;
    items.clear();
    counter += 1;
  }

  exit(EXIT_SUCCESS);
}

외부while루프는 기본 구분 기호 인 개행 문자를 사용하여getline을 호출하는 반면 내부 루프는 쉼표 문자를 세 번째 인수로 지정합니다. 이전 샘플 코드와 달리 다음 코드는 필드의 후행 공백을 처리하고 데이터 단위를벡터에 저장하기 전에 구문 분석하는 솔루션을 구현합니다. 따라서,push_back이 호출되기 직전에 내부while루프에erase-remove관용구를 추가했습니다. isspace함수 객체를remove_if인수로 사용하므로 공백, 탭, 캐리지 리턴 등과 같은 공백 문자를 처리합니다.

#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::ostringstream;
using std::string;

string readFileIntoString(const string& path) {
  auto ss = ostringstream{};
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  ss << input_file.rdbuf();
  return ss.str();
}

int main() {
  string filename("grades.csv");
  string file_contents;
  std::map<int, std::vector<string>> csv_contents;
  char delimiter = ',';

  file_contents = readFileIntoString(filename);

  istringstream sstream(file_contents);
  std::vector<string> items;
  string record;

  int counter = 0;
  while (std::getline(sstream, record)) {
    istringstream line(record);
    while (std::getline(line, record, delimiter)) {
      record.erase(std::remove_if(record.begin(), record.end(), isspace),
                   record.end());
      items.push_back(record);
    }

    csv_contents[counter] = items;
    items.clear();
    counter += 1;
  }

  exit(EXIT_SUCCESS);
}
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C++ File