Las funciones ctime en C devuelven la misma cadena para diferentes valores de atime, mtime y ctime?
Cuando se utiliza la stat()
función en Mingw-W64, y la estructura se vuelve, aquí info
, ¿por qué ctime
volver las mismas cadenas exactas para info.st_atime
, mtime
y ctime
, a pesar de que los sus valores enteros son diferentes?
Si localtime
se utiliza para obtener cada componente de tiempo por separado, los resultados difieren y parecen precisos; es decir, coinciden con las fechas de las carpetas de archivos que he observado.
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
Hace más de tres años se hizo una pregunta similar sin respuesta.
¿Alguien sabe por qué y si hay o no documentación sobre las fechas en minGW-W64?
Gracias.
Aquí está el ejemplo de código completo. Es un conjunto de impresión feo.
#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;
}
Los resultados de un archivo tienen el siguiente aspecto.
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
Tenga en cuenta que las cadenas de datos de ctime()
son idénticas, aunque los valores enteros difieren para los tres. Además, el valor entero de ctime
es un formato diferente al de atime
y mtime
. Los atime
y mtime
parecen ser segundos desde el 1 de enero de 1970, pero no sé qué ctime
es como 5767254
.
Gracias.
Código fijo según comentario de @KamilCuk. Mi estupidez y mi fea impresión fueron la causa. Cambios a continuación y nuevos resultados.
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 );
Nuevos resultados.
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
Respuestas
Básicamente estás haciendo:
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
}
Todas asctime
(implementaciones sensatas) escriben en la misma memoria y devuelven el mismo puntero . Entonces, cuando printf
se ejecuta, solo imprime el contenido de la misma memoria. Tenga en cuenta que el orden de evaluación de los argumentos de las funciones no está secuenciado entre sí, pero el orden de evaluación de las llamadas a funciones tiene una secuencia indeterminada. Cualquiera de los posibles resultados de asctime
será válido. Use asctime_r
o llame uno tras otro en printf
s separados .