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++的主要内容,如果未能解决你的问题,请参考以下文章

java 使用 opencsv 封装csv导入导出工具 中文乱码

即时将 csv 文件添加到 zip 文件以进行导出和导入

Java:使用OpenCSV解析CSV文件

用opencsv文件读写CSV文件

使用OpenCSV用Java编写CSV文件

OpenCSV:如何使用自定义列标题和自定义列位置从 POJO 创建 CSV 文件?