Question

First of all, my knowledge of X++ is minimal, I just need to edit the code I've been given. I have a C++ program which creates a text file and stores data in it. Right now the program is using:

outfile.open("C:/Users/Admin/Documents/MATLAB/datafile.txt", std::ios::app);

But I need to change this code so each time i run this code, it will create a new file name. My suggestion is to somehow incorporate the time/date as the file name, but I am unsure how to do this. I've tried researching around, and it looks like using time_t is the way to go, but I'm unsure how to utilize it for my case.

Is it possible to save the time/date as a variable, then use:

outfile.open("C:/Users/td954/Documents/MATLAB/<DEFINED VARIABLE>", std::ios::app);
//                                            ^^^^^^^^^^^^^^^^^^

if so, how would I go about this?

Thanks guys

Was it helpful?

Solution

Here's code:

time_t currentTime = time(0);
tm* currentDate = localtime(&currentTime);
char filename[256] = {0};

strcpy(filename, "C:/Users/Admin/Documents/MATLAB/datafile");
strcat(filename, fmt("-%d-%d-%d@%d.%d.%d.txt",
       currentDate->tm_hour, currentDate->tm_min, currentDate->tm_sec,
       currentDate->tm_mday, currentDate->tm_mon+1,
       currentDate->tm_year+1900).c_str());

outfile.open(filename, std::ios::app);

tm* and time_t are in ctime header. fmt is just function like sprintf, which formats string. Implementation(not mine, found on stackoverflow IIRC):

#include <cstdarg>
std::string fmt(const std::string& fmt, ...) {
    int size = 200;
    std::string str;
    va_list ap;
    while (1) {
        str.resize(size);
        va_start(ap, fmt);
        int n = vsnprintf((char*)str.c_str(), size, fmt.c_str(), ap);
        va_end(ap);
        if (n > -1 && n < size) {
            str.resize(n);
            return str;
        }
        if (n > -1)
            size = n + 1;
        else
            size *= 2;
    }
    return str;
}

OTHER TIPS

Sure, you can do something like this:

// Calculate the path
time_t current_time = time(nullptr);
std::ostringstream path_out(prefix);
path_out << "-" < < current_time << ".txt";
std::string path = path_out.str();

// Open a file with the specified path.
std::ofstream out(path.c_str(), std::ios::app);

// do stuff with "out"

That being said, if you are trying to use the time for the filename in order to create temporary files, then the solution you are looking for is likely platform-specific. On UNIX-based systems, mkstemp is the preferred way to create temporary files (I'm not sure what the preferred way to do this is on Windows, but who cares ;)).

You can use a timestamp provided through the date and time facilities of C++11. In particular, the now() function of the std::chrono namespace will return what you want:

#include <chrono>

std::ostringstream oss;
oss << "myfile" << std::chrono::system_clock::now() << ".txt";
//                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

std::ofstream out(oss.str(), std::ios_base::app);
#include <ctime>
#include <stdexcept>
#include <sstream>

std::string getTimestampedFilename(const std::string &basePathname) {
   std::ostringstream filename;
   filename << basePathname << '.' << static_cast<unsigned long>(::time(0));
   return filename.str();
}

Now, you can use this elsewhere...

template<class T>
void writeToFile(const std::string &basePathname, T data) {
    std::string filename = getTimestampedFilename(basePathname);
    std::ofstream outfile(filename.c_str());

    if (outfile) {
       outfile << data;
    }
    else {
       throw std::runtime_error("Cannot open '" + filename + "' for writing.");
    }
}

Try something like this:

std::time_t t = std::time(NULL);
std::tm *ptm = std::localtime(&t);
std::stringstream ss;
ss << ptm->tm_year+1900 << std::setw(2) << ptm->tm_mon+1 << ptm->tm_mday << ptm->tm_hour+1 << ptm->tm_min+1 << ptm->tm_sec+1;
outfile.open(("C:/Users/Admin/Documents/MATLAB/datafile_"+ss.str()+".txt").c_str(), std::ios::app);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top