'Displaying date and time in the file name

I'm trying to create a file with the current date and time (seperated by underscores) as the file name, but I get the following error when compiling:

main.c:45:31: error: ‘%02d’ directive writing between 2 and 11 bytes into a region of size between 1 and 17 [-Werror=format-overflow=]
   45 |   sprintf(fileName,"%04d_%02d_%02d_%02d_%02d_%02d",ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,ptm->tm_sec);
cc1: all warnings being treated as errors

How do I suppress this warning/solve this issue?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <time.h>

int main(int argc, char *argv[]) {
  time_t rawtime;
  time(&rawtime);
  struct tm * ptm = localtime(&rawtime);
  char fileName[25];
  sprintf(fileName,"%04d_%02d_%02d_%02d_%02d_%02d",ptm->tm_year + 1900, ptm->tm_mon+1,
    ptm->tm_mday, ptm->tm_hour, ptm->tm_min,ptm->tm_sec);
}
c


Solution 1:[1]

To limit the conversion of "%02d" to 2 digits, perform a % 100u on the int and use "%02u".

sprintf(fileName,"%04u_%02u_%02u_%02u_%02u_%02u",
  (ptm->tm_year + 1900) % 10000u, (ptm->tm_mon+1)%100u, ptm->tm_mday%100u,
  ptm->tm_hour%100u, ptm->tm_min%100u, ptm->tm_sec%100u);

Or be prepared for the worse case outputs

// 5 _ and 6 INT_MIN and \0
char fileName[5 + 6*11 + 1];
sprintf(fileName,"%04du_%02d_%02d_%02d_%02d_%02d",
  ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday
  ptm->tm_hour, ptm->tm_min, ptm->tm_sec);

Solution 2:[2]

Another approach you can take is to use snprintf (NULL, 0, format, vals...) to determine the number of characters that would have been written (excluding the terminating null byte) had enough space been available. So you can size fileName using:

  char fileName[snprintf(NULL, 0, format, vals...) + 1];

In your case that could be:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <time.h>

int main (void) {
  
  time_t rawtime;
  time(&rawtime);
  struct tm *ptm = localtime(&rawtime);
  
  /* use snprintf (NULL, 0, format, vals...) to find max number of chars
   * required (excluding the terminating null-byte).
   */
  char fileName[snprintf(NULL, 0,"%04d_%02d_%02d_%02d_%02d_%02d",
                        ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, 
                        ptm->tm_hour, ptm->tm_min,ptm->tm_sec) + 1];
  
  sprintf(fileName,"%04d_%02d_%02d_%02d_%02d_%02d",
          ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, 
          ptm->tm_hour, ptm->tm_min,ptm->tm_sec);
}

Also note argc and argv are not used in your program, so the proper invocation of main() is int main (void) to make it explicit that your program takes no arguments (and avoid any -Wunused warnings...).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 David C. Rankin