Les fonctions ctime en C retournent la même chaîne pour des valeurs différentes de atime, mtime et ctime?

Nov 28 2020

Lorsque vous utilisez la stat()fonction MinGW-W64 et la struct retourne, ici info, pourquoi ctimeretourner les mêmes chaînes exactes pour info.st_atime, mtimeet ctime, même si les leurs valeurs entières sont différentes?

Si localtimeest utilisé pour obtenir chaque composante de temps séparément, les résultats diffèrent et semblent exacts; c'est-à-dire qu'ils correspondent aux dates dans les dossiers de fichiers que j'ai observés.

ctime(&info.st_atime )  versus   localtime(&info.st_atime )->tm_wday,
                                 localtime(&info.st_atime )->tm_mon,
                                 localtime(&info.st_atime )->tm_mday,
                                 localtime(&info.st_atime )->tm_hour,
                                 localtime(&info.st_atime )->tm_min,
                                 localtime(&info.st_atime )->tm_sec,
                                 localtime(&info.st_atime )->tm_year

Une question similaire a été posée il y a plus de trois ans sans réponse.

Est-ce que quelqu'un sait pourquoi et s'il existe ou non une documentation sur les dates dans minGW-W64?

Je vous remercie.


Voici l'exemple de code complet. C'est un ensemble de printf laid.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>

int main (void)

{
  DIR *dp;
  struct dirent *ep;
  struct stat info;
  int rc;
  char fl_name[300];

  dp = opendir("./SQLite3");

  if ( dp != NULL )
    {
      while ( ep = readdir( dp ) )
        {
          printf( "Name : %s, ", ep->d_name );
          if ( *( ep->d_name ) == '.' )
            { 
              printf(" non-useful file\n");
              continue;
            }

          sprintf( fl_name, "%s%s", "./SQLite3/", ep->d_name );

          if ( ( rc = stat( fl_name, &info ) ) != 0 )
             {
               printf( "rc : %d\n", rc );
               printf( "errno : %d, strerror : %s\n", errno, strerror( errno ) );
               break;
             }

          printf( "mode : %d, size : %d,\nst_atime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n"           
                                        "st_mtime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n"          
                                        "st_ctime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n\n",

                  info.st_mode, info.st_size, 
                  ctime(&info.st_atime ),
                  localtime(&info.st_atime )->tm_wday,
                  localtime(&info.st_atime )->tm_mon,
                  localtime(&info.st_atime )->tm_mday,
                  localtime(&info.st_atime )->tm_hour,
                  localtime(&info.st_atime )->tm_min,
                  localtime(&info.st_atime )->tm_sec,
                  localtime(&info.st_atime )->tm_year,
                  info.st_atime,

                  ctime(&info.st_mtime ),
                  localtime(&info.st_mtime )->tm_wday,
                  localtime(&info.st_mtime )->tm_mon,
                  localtime(&info.st_mtime )->tm_mday,
                  localtime(&info.st_mtime )->tm_hour,
                  localtime(&info.st_mtime )->tm_min,
                  localtime(&info.st_mtime )->tm_sec,
                  localtime(&info.st_mtime )->tm_year,
                  info.st_mtime,

                  ctime(&info.st_ctime ),
                  localtime(&info.st_ctime )->tm_wday,
                  localtime(&info.st_ctime )->tm_mon,
                  localtime(&info.st_ctime )->tm_mday,
                  localtime(&info.st_ctime )->tm_hour,
                  localtime(&info.st_ctime )->tm_min,
                  localtime(&info.st_ctime )->tm_sec,
                  localtime(&info.st_ctime )->tm_year ),
                  info.st_ctime;    
        }    
      printf( "Now : %ld\n", time(NULL) );
      printf( "Broke" );
      (void) closedir (dp);
    }
  else
    perror ("Couldn't open the directory");    
  return 0;
}

Les résultats pour un fichier se présentent comme suit.

Name : testing.c, mode : 33206, size : 21092,
st_atime : Thu Nov 26 23:56:20 2020
local : 4 10 26 23 : 56 : 20 120,
integer value : 1606452980
st_mtime : Thu Nov 26 23:56:20 2020
local : 5 10 27 0 : 16 : 58 120,
integer value : 1606454218
st_ctime : Thu Nov 26 23:56:20 2020
local : 6 9 31 23 : 8 : 28 120,
integer value : 5767254

Notez que les chaînes de données de ctime()sont identiques bien que les valeurs entières diffèrent pour les trois. En outre, la valeur entière pour ctimeest un format différent de celui pour atimeet mtime. Les atimeet mtimesemblent être des secondes depuis le 1er janvier 1970 mais je ne sais pas ce que ctimec'est 5767254.

Merci.


Code fixe selon le commentaire de @KamilCuk. Ma stupidité et ma laideur en étaient la cause. Modifications ci-dessous et nouveaux résultats.

  struct tm *local_tm_ptr;

    
          local_tm_ptr = localtime(&info.st_atime );
          printf( "mode : %d, size : %d,\nst_atime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n",           
                  info.st_mode, info.st_size, 
                  ctime(&info.st_atime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_atime );


          local_tm_ptr = localtime(&info.st_mtime );
          printf( "st_mtime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n",
                  ctime(&info.st_mtime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_mtime );


          local_tm_ptr = localtime(&info.st_ctime );
          printf( "st_ctime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n\n",
                  ctime(&info.st_ctime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_ctime );

Nouveaux résultats.

Name : testing.c, mode : 33206, size : 21092,
st_atime : Thu Nov 26 23:56:20 2020
local : 4 10 26 23 : 56 : 20 120,
integer value : 1606452980
st_mtime : Fri Nov 27 00:16:58 2020
local : 5 10 27 0 : 16 : 58 120,
integer value : 1606454218
st_ctime : Sat Oct 31 23:08:28 2020
local : 6 9 31 23 : 8 : 28 120,
integer value : 1604200108

Réponses

2 KamilCuk Nov 29 2020 at 03:10

Vous faites essentiellement:

static char buffer[20]; // static buffer internal for asctime
char *my_asctime(int a) { // asctime
    snprintf(buffer, 20, "%d", a); // asctime converts the input to some output
    return buffer; // and returns pointer to internal buffer
}
int main() {
    printf("%s %s %s %s\n", 
       my_asctime(1),
       my_asctime(2),
       my_asctime(3),
       my_asctime(4)
   );
    // **Any** of the outputs are valid:
    // 1 1 1 1
    // 2 2 2 2
    // 3 3 3 3
    // 4 4 4 4
}

Toutes asctime(implémentations saines) écrivent dans la même mémoire et renvoient le même pointeur . Donc, quand printfest exécuté, il va simplement imprimer le contenu de la même mémoire. Notez que l' ordre d'évaluation des arguments des fonctions n'est pas séquencé les uns avec les autres, mais que l'ordre d'évaluation des appels de fonction est indéterminé. N'importe lequel des résultats possibles de asctimesera valide. Utilisez asctime_rou appelez l'un après l'autre dans des printfs.