aliants
aliants

Reputation: 77

"Sprintf" deletes the value assigned to a variable not invoked in the call

I have this piece of code in my application:

void dateToString(char * epoch, struct tm * data) {
    int year, month, day, hour, minute, second;

    year = data->tm_year + 1900;
    month = data->tm_mon + 1;
    day = data->tm_mday;
    hour = data->tm_hour;
    minute = data->tm_min;
    second = data->tm_sec;

    sprintf(epoch, "%04d-%02d-%02dT%02d:%02d:%02d.0Z", year, month, day, hour, minute, second);
}

...
(in main function)
...
currentDate = gmtime(&currentTime);
dateToString(epoch, currentDate);
sprintf(timeIntMs, "%05u", tiMs);
measFile << epoch << "," << measBuffer; measFile.flush();

where:

ofstream measFile;
unsigned int tiMs;
struct tm * currentDate;        // to storage current time [dd-mm-yyyy h:m:s]
char measBuffer[256];
time_t currentTime;
char epoch[23];
char timeIntMs[5];

The problem is that in this case in my measFile output file the value of epoch is empty (i.e. string with length 0), while if I change the order of the calls like this:

currentDate = gmtime(&currentTime);
dateToString(epoch, currentDate);
measFile << epoch << "," << measBuffer; measFile.flush();
sprintf(timeIntMs, "%05u", tiMs);

i.e. by moving the sprintf call after the saving of the file the variable epoch maintains its own value (e.g. 2015-11-08T11:06:05.0Z).

What's wrong in this code?

Upvotes: 0

Views: 331

Answers (1)

M.M
M.M

Reputation: 141554

You are writing out of bounds with timeIntMs.

Instead do char timeIntMs[6]; and then sprintf(timeIntMs, "%05u", tiMs % 100000); . Read about null termination; and the 5 in %05u is a minimum field width, not a maximum.

Preferably use snprintf instead, as then even if you make a mistake in arithmetic, you won't cause a buffer overflow.

Upvotes: 4

Related Questions