C++로 CSV 파일 읽기
이 기사에서는 C++에서 CSV 파일을 읽는 방법에 대한 몇 가지 방법을 설명합니다.
std::getline
및std::istringstream
을 사용하여 C++에서 CSV 파일 읽기
CSV 파일은 일반적으로 텍스트 파일 형식으로 알려져 있으며 각 행에서 값이 쉼표로 구분됩니다. 행을 데이터 레코드라고하며 각 레코드는 일반적으로 쉼표로 구분 된 둘 이상의 필드로 구성됩니다. CSV 형식은 대부분 테이블 형식 데이터를 저장하는 데 사용되므로 각 레코드에 동일한 수의 쉼표 구분 기호를 포함합니다. 그러나 실제로 여러 구현이 있기 때문에 예를 들어 쉼표로 구분 된 필드 사이에 공백이 있거나 필드 사이에 공백이 없을 수 있습니다. 다음 예에서는 사이에 공백이 없다고 가정합니다. 구역. 따라서 쉼표 사이의 모든 문자는 단일 데이터 단위로 간주됩니다.
먼저 파일 내용을 읽고std::string
객체에 저장해야합니다. readFileIntoString
함수는std::ostringstream
및rdbuf
를 사용하여 파일을 읽고string
값을 호출자 함수에 반환합니다. 이전 단계가 성공적으로 완료되면string
객체에서std::istringstream
을 생성하고 각 행을 반복 할 수 있습니다. 이 반복에서는 라인의 각 필드를 추출하고std::vector
에 저장하는 또 다른 루프를 넣습니다. 모든 라인 반복의 끝에서vector
를std::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);
}
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