OpenCSV快速方便导出CSV文件拿虾C++
Posted 易拿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCSV快速方便导出CSV文件拿虾C++相关的知识,希望对你有一定的参考价值。
项目源代码:https://github.com/openlinyou/opencsv
使用C++分析大数据的时候,数据按CSV格式导出,可以用Excel分析数据。
OpenCSV非常易用和简单。
测试例子:
#include <assert.h>
#include "opencsv.h"
int main()
std::string buffer1;
std::string buffer2;
//生成CSV数据
OpenCSV csv = "ID", "name", "salary" ;
csv = "1", "Jack", "100000" ;
csv = "2", "Tom", "80000" ;
csv = std::to_string(3), "Lucy", "50000" ;
csv >> buffer1;
buffer2 = "ID,name,salary\\n"
"1,Jack,100000\\n"
"2,Tom,80000\\n"
"3,Lucy,50000\\n";
assert(buffer1 == buffer2);
//解析CSV数据
OpenCSV csv;
csv << buffer2;
buffer1 = "ID,name,salary\\n";
for (size_t i = 1; i < csv.size(); ++i)
auto& line = csv[i];
buffer1.append(line["ID"] + "," + line["name"] + "," + line["salary"] + "\\n");
assert(buffer1 == buffer2);
std::string filePath = "./test.csv";
//生成CSV文件
OpenCSV csv;
csv << buffer2;
assert(csv[0][0] == "ID");
assert(csv[0][2] == "salary");
csv[1]["salary"] = std::to_string(10000);
csv[2]["salary"] = "8000";
csv[3]["salary"] = "5000";
csv >> filePath; //自动判断是否是路径
buffer2 = "ID,name,salary\\n"
"1,Jack,10000\\n"
"2,Tom,8000\\n"
"3,Lucy,5000\\n";
//加载CSV文件
OpenCSV csv;
csv << filePath; //自动判断是否是路径
buffer1.clear();
csv >> buffer1;
assert(buffer1 == buffer2);
return 0;
跨平台支持:
Windows、linux
源文件列表:
src/opencsv.h
src/opencsv.cpp
运行测试例子
cd ./opencsv
mkdir build
cd build
cmake ..
make
./test
源文件:
src/opencsv.h
/***************************************************************************
* Copyright (C) 2023-, openlinyou, <linyouhappy@outlook.com>
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
***************************************************************************/
#ifndef HEADER_OPEN_CSV_H
#define HEADER_OPEN_CSV_H
#include <string>
#include <vector>
class OpenCSV
typedef std::vector<std::string> Line;
class CSVLine
Line line_;
OpenCSV* csv_;
CSVLine()
:csv_(0)
friend class OpenCSV;
public:
CSVLine(OpenCSV* csv)
:csv_(csv)
CSVLine(const CSVLine& csvline)
csv_ = csvline.csv_;
if (!csvline.line_.empty())
line_ = csvline.line_;
inline size_t size() return line_.size();
inline bool empty() return line_.empty();
inline Line& line() return line_;
std::string& operator[](size_t idx);
std::string& operator[](const std::string& key);
;
typedef const std::initializer_list<std::string> List;
std::vector<CSVLine> lines_;
std::string emptyStr_;
friend class CSVLine;
public:
OpenCSV()
OpenCSV(List& list);
void operator=(List& list);
//OpenCSV(OpenCSV& csv);
//void operator=(OpenCSV& csv);
inline bool empty() return lines_.empty();
inline size_t size() return lines_.size();
CSVLine& operator[](size_t idx);
void operator>>(std::string& output);
void operator<<(const std::string& output);
inline std::vector<CSVLine>& lines() return lines_;
;
#endif /* HEADER_OPEN_CSV_H */
src/opencsv.cpp
#include "opencsv.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <string>
#include <vector>
static bool CheckFilePath(const std::string& filePath);
static int64_t ReadFile(const std::string& filePath, std::string& buffer, const char* m);
static int64_t WriteFile(const std::string& filePath, std::string& buffer, const char* m);
std::string& OpenCSV::CSVLine::operator[](size_t idx)
if (idx >= line_.size())
line_.resize(idx + 1);
return line_[idx];
std::string& OpenCSV::CSVLine::operator[](const std::string& key)
OpenCSV* csv = dynamic_cast<OpenCSV*>(csv_);
if (csv == 0 || csv->lines_.empty())
static std::string emptyStr;
assert(false);
return emptyStr;
CSVLine& keyLine = csv->lines_[0];
size_t idx = 0;
for (; idx < keyLine.size(); ++idx)
if (keyLine[idx] == key) break;
if (idx < keyLine.size())
return line_[idx];
assert(false);
csv->emptyStr_.clear();
return csv->emptyStr_;
OpenCSV::OpenCSV(List& list)
if (list.size() > 0)
lines_.resize(lines_.size() + 1, CSVLine(this));
lines_.back().line() = list;
void OpenCSV::operator=(List& list)
if (list.size() > 0)
lines_.resize(lines_.size() + 1, CSVLine(this));
lines_.back().line() = list;
//OpenCSV::OpenCSV(OpenCSV& csv)
//
// lines_ = csv.lines();
//
//void OpenCSV::operator=(OpenCSV& csv)
//
// lines_ = csv.lines();
//
OpenCSV::CSVLine& OpenCSV::operator[](size_t idx)
if (idx >= lines_.size())
lines_.resize(idx + 1, CSVLine(this));
return lines_[idx];
void OpenCSV::operator>>(std::string& output)
std::string str;
for (auto& line : lines_)
if (line.empty()) continue;
for (size_t j = 0; j < line.size(); ++j)
str.append(j > 0 ? "," + line[j] : line[j]);
str.append("\\n");
if (!CheckFilePath(output))
output.append(str);
return;
WriteFile(output, str, "wb");
void OpenCSV::operator<<(const std::string& input)
std::string buffer;
if (CheckFilePath(input))
ReadFile(input, buffer, "rb");
else
buffer = input;
lines_.clear();
if (buffer.empty()) return;
size_t row = 0;
size_t column = 0;
for (size_t i = 0; i < buffer.size(); ++i)
if (buffer[i] == '\\n')
if (!lines_.back().empty())
++row;
column = 0;
continue;
if (buffer[i] == ',')
++column;
continue;
(*this)[row][column].push_back(buffer[i]);
static bool CheckFilePath(const std::string& filePath)
if (!filePath.empty() && filePath.size() < 1024)
if (!strstr(filePath.c_str(), "\\n") && !strstr(filePath.c_str(), ","))
if (strstr(filePath.c_str(), "/")) return true;
return false;
static int64_t ReadFile(const std::string& filePath, std::string& buffer, const char* m)
FILE* f = fopen(filePath.c_str(), m);
if (!f) return -1;
fseek(f, 0, SEEK_END);
long len = ftell(f);
fseek(f, 0, SEEK_SET);
buffer.resize(len, 0);
size_t ret = fread((void*)buffer.data(), 1, len, f);
fclose(f);
return ret == 0 ? -1 : len;
static int64_t WriteFile(const std::string& filePath, std::string& buffer, const char* m)
FILE* f = fopen(filePath.c_str(), m);
if (!f) return -1;
size_t ret = fwrite((void*)buffer.data(), 1, buffer.size(), f);
fclose(f);
return ret == 0 ? -1 : buffer.size();
以上是关于OpenCSV快速方便导出CSV文件拿虾C++的主要内容,如果未能解决你的问题,请参考以下文章