Skip to main content

Raymii.org Logo (IEC resistor symbol) logo

Quis custodiet ipsos custodes?
Home | About | All pages | RSS Feed | Gopher

C++ create and write to a CSV file

Published: 07-06-2019 | Author: Remy van Elst | Text only version of this article


Table of Contents


In this quick snippet I'll show you how to create and write to a csv file. It includes checking if the file is writable, and if it's not there, creates it with a different first row as header. It's a quick example, I've used it to log some test data. It can probably be improved. It does use a mutex and guard_lock so it should be thread safe.

If you like this article, consider sponsoring me by trying out a Digital Ocean VPS. With this link you'll get $100 credit for 60 days). (referral link)

write_csv.cpp

The first method checks if the file exists. The second method is a template, but with a set amount of columns (since that was enough in my case). The types could differ which is why I opted for a template.

Note that this is a cut-down simplified example, in the next section I list some possible improvements. Since this was a one-off user story for some tests, the time allocated wasn't much, thus making the code bare.

In main() there is an example with different types and a loop to show how you could use the function.

#include <iostream>
#include <mutex>
#include <fstream>

std::mutex logMutex;

bool fileExists(std::string& fileName) {
    return static_cast<bool>(std::ifstream(fileName));
}

template <typename filename, typename T1, typename T2, typename T3>
bool writeCsvFile(filename &fileName, T1 column1, T2 column2, T3 column3) {
    std::lock_guard<std::mutex> csvLock(logMutex);
    std::fstream file;
    file.open (fileName, std::ios::out | std::ios::app);
    if (file) {
        file << "\"" << column1 << "\",";
        file << "\"" << column2 << "\",";
        file << "\"" << column3 << "\"";
        file <<  std::endl;
        return true;
    } else {
        return false;
    }
}

int main() {
    std::string csvFile = "logfile2.csv";
    std::string naam = "Hallo";
    if(!fileExists(csvFile))
        writeCsvFile(csvFile, "header1", "header2", "header3");

    for (int i = 1; i < 10; ++i) {
        if (!writeCsvFile(csvFile, i, naam, static_cast<float>(i * 3.5))) {
            std::cerr << "Failed to write to file: " << csvFile << "\n";
        }
    }
    return 0;
}

The example logfile.csv looks like this after two runs:

"header1","header2","header3"
"1","Hallo","3.5"
"2","Hallo","7"
"3","Hallo","10.5"
"4","Hallo","14"
"5","Hallo","17.5"
"6","Hallo","21"
"7","Hallo","24.5"
"8","Hallo","28"
"9","Hallo","31.5"
"1","Hallo","3.5"
"2","Hallo","7"
"3","Hallo","10.5"
"4","Hallo","14"
"5","Hallo","17.5"
"6","Hallo","21"
"7","Hallo","24.5"
"8","Hallo","28"
"9","Hallo","31.5"
"1","Hallo","3.5"
"2","Hallo","7"
"3","Hallo","10.5"
"4","Hallo","14"
"5","Hallo","17.5"
"6","Hallo","21"
"7","Hallo","24.5"
"8","Hallo","28"
"9","Hallo","31.5"

Possible improvements

Tags: c++ , cpp , csv , development , linux , snippets , software