Ankit Bhardwaj
Ankit Bhardwaj

Reputation: 89

Trying to create a dynamic csv file based on UTC time

I am trying to create a file from C++ code with format(name + UTC Date Time) using std::fstream, but every time it is showing that it cannot create a file that I am printing using std::cout. No idea why this is happening.

Below is the code which is printing the output:

void IOfile::writeCsv(string write_file) {
    write_file.erase(std::remove_if(write_file.begin(), write_file.end(), ::isspace), write_file.end());
    cout << write_file.size() << endl;
    cout << write_file << endl;
    string placeholder = ".csv";
    string finalFile = write_file + placeholder;
    
    cout << finalFile.size()<<endl;
    cout << finalFile<< endl;

    fstream file;
    file.open(finalFile, fstream::out);
    if (!file)
    {
        cout << "Error in creating file!!!";
    }
    else {
        cout << "File created successfully.";
    }
    file.close();
}  

Place where the writeCSV() function is getting called. Data in below code is object of the class which contains the writeCSV function:

string dateTime = data.getDateTime();
string fileName = "Big" + dateTime;

Above code is calling one function getDateTime() which is returning the current GMT time.

string IOfile::getDateTime()
{
    time_t now = time(0);
    char* currentTime = ctime(&now);

    tm* gmtm = gmtime(&now);//to get GMT time
    currentTime = asctime(gmtm);

    return currentTime;
};

Output which I am getting:

23
BigMonApr2422:45:572023
27
BigMonApr2422:45:572023.csv
Error in creating file!!!

Upvotes: 0

Views: 66

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597941

On many systems, you can't use : in a file name. For example, on Windows:

Naming Files, Paths, and Namespace

The following fundamental rules enable applications to create and process valid names for files and directories, regardless of the file system:

  • ...

  • Use any character in the current code page for a name, including Unicode characters and characters in the extended character set (128–255), except for the following:

    • The following reserved characters:
      • < (less than)
      • > (greater than)
      • : (colon)
      • " (double quote)
      • / (forward slash)
      • \ (backslash)
      • | (vertical bar or pipe)
      • ? (question mark)
      • * (asterisk)
  • ...

Also see this question: Allowed characters in filename

So, you need to change the : characters to something more acceptable, like - or _, or just eliminate them completely.

Also, consider using functions that give you control over the formatting of your file name, so that you can include only what you actually want rather than removing what you don't want.

For example, using std::strftime():

#include <ctime>

string IOfile::makeCsvFileName()
{
    time_t now = time(nullptr);

    char buffer[32] = {};
    strftime(buffer, size(buffer), "Big%a%b%d%H_%M_%S%Y.csv", gmtime(&now));

    return buffer;
}

void IOfile::writeCsv(string write_file) {

    cout << write_file.size() << endl;
    cout << write_file << endl;

    string placeholder = ".csv";
    string finalFile = write_file + placeholder;
    
    cout << finalFile.size() <<endl;
    cout << finalFile << endl;

    ofstream file(finalFile);
    if (!file) {
        cout << "Error in creating file!!!";
    }
    else {
        cout << "File created successfully.";
        file.close();
    }
}

...

string fileName = makeCsvFileName();
writeCsv(fileName);

Or, using std:::put_time:

#include <sstream>
#include <iomanip>
#include <ctime>

string IOfile::makeCsvFileName()
{
    time_t now = time(nullptr);

    ostringstream oss;
    oss << put_time(gmtime(&now), "Big%a%b%d%H_%M_%S%Y.csv");

    return oss.str();
}

Or, using std::format():

#include <format>
#include <chrono>

string IOfile::makeCsvFileName()
{
    return std::format(
        "Big{0:%a}{0:%b}{0:%d}{0:%H}_{0:%M}_{0:%S}{0:%Y}.csv",
        std::chrono::utc_clock::now()
    );
}

Just on a side note: a file name like BigMonApr2422:45:572023.csv is a little hard to read/understand, especially the 2422 and 572023 portions. Consider using more readable file names, for example: Big_YYYY-MM-DD_HH-MM-SS.csv like Big_2023-04-24_22-45-57.csv

Upvotes: 2

Related Questions