is there any library or example for reading a csv file in C++ like the csv module in Python?
What I need is a function to read a csv file and put each column element of a row in a map with the header name as the key value.
is there any library or example for reading a csv file in C++ like the csv module in Python?
What I need is a function to read a csv file and put each column element of a row in a map with the header name as the key value.
I can answer myself. I wrote a CSVDict class.
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
class CSVDict {
public:
CSVDict(std::string fileName, int headerRow) {
file = std::ifstream(fileName);
for (int i = 0; i < headerRow; i++){ readNextRow(file); }
m_header = m_data;
}
std::string const& operator[](std::size_t index) const {
return m_data[index];
}
std::string const& operator[](std::string index) const {
return m_dataMap.find(index)->second;
}
bool readNextRowMap() {
readNextRow(file);
if (!file) return false;
m_dataMap.clear();
auto it_data = m_data.begin();
for (auto it = m_header.begin(); it != m_header.end(); ++it) {
m_dataMap[*it] = *it_data;
++it_data;
}
return true;
}
private:
void readNextRow(std::istream& str) {
std::string line;
std::getline(str, line);
if (!str) return;
std::stringstream lineStream(line);
std::string cell;
m_data.clear();
while (std::getline(lineStream, cell, ';')) {
m_data.push_back(cell);
}
}
std::vector<std::string> m_data;
std::vector<std::string> m_header;
std::map<std::string, std::string> m_dataMap;
std::ifstream file;
};
int main()
{
CSVDict dict("1.csv", 2);
while (dict.readNextRowMap()) {
std::cout << dict[0] << " " << dict[1] << " " << dict[2] << " " << dict[3] << " " << dict[4] << " " << dict[5] << " " << dict[6] << "\n";
}
CSVDict dict1("1.csv", 2);
dict1.readNextRowMap();
std::cout << dict1["ipField"] << " " << dict1["mdBeamEnergy"] << " " << dict1["mdBeamCurrent"] << " " << dict1["mcoBeamSizeId"] << " " << dict1["mdGantryAngle"] << " " << dict1["miLayerNumber"] << "\n";
dict1.readNextRowMap();
std::cout << dict1["ipField"] << " " << dict1["mdBeamEnergy"] << " " << dict1["mdBeamCurrent"] << " " << dict1["mcoBeamSizeId"] << " " << dict1["mdGantryAngle"] << " " << dict1["miLayerNumber"] << "\n";
dict1.readNextRowMap();
std::cout << dict1["ipField"] << " " << dict1["mdBeamEnergy"] << " " << dict1["mdBeamCurrent"] << " " << dict1["mcoBeamSizeId"] << " " << dict1["mdGantryAngle"] << " " << dict1["miLayerNumber"] << "\n";
dict.readNextRowMap();
std::cout << dict[0] << " " << dict[1] << " " << dict[2] << " " << dict[3] << " " << dict[4] << " " << dict[5] << " " << dict[6] << "\n";
return 0;
}
Example csv file:
#VALUES;;;;;;
ipField;mdBeamEnergy;mdBeamCurrent;mcoBeamSizeId;mdGantryAngle;miLayerNumber;mbRoomSwitchingLayer
24.30815;172.152971;24.30815;4;65;1;1
24.30815;172.152971;24.30815;4;65;2;0
24.30815;172.152971;24.30815;4;65;3;0
24.30815;172.152971;24.30815;4;65;4;0
24.30815;172.152971;24.30815;4;65;5;0
24.30815;172.152971;24.30815;4;65;6;0
24.30815;172.152971;24.30815;4;65;7;0
24.30815;172.152971;24.30815;4;65;8;0
usage (see main function in example):
class constructor needs to have the csv filename and the csv header line number every readNextRowMap gets the values of the next line in the csv file you can address the values either by number index or by header name
downside:
csv file has to have a header line