Funkcje ctime w C zwracają ten sam ciąg dla różnych wartości atime, mtime i ctime?
Podczas korzystania z stat()
funkcji w MinGW-W64, a struct zwraca tutaj info
, dlaczego nie ctime
powrócić dokładnie taki sam dla ciągów info.st_atime
, mtime
i ctime
, chociaż ich wartości całkowite są różne?
Jeśli localtime
jest używane do oddzielnego pobierania każdego składnika czasu, wyniki różnią się i wydają się dokładne; to znaczy, pasują do dat w folderach plików, które zaobserwowałem.
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
Podobne pytanie zadano ponad trzy lata temu bez odpowiedzi.
Czy ktoś wie dlaczego i czy jest jakaś dokumentacja dotycząca dat w minGW-W64?
Dziękuję Ci.
Oto przykład pełnego kodu. To brzydki zestaw printf.
#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;
}
Wyniki dla jednego pliku wyglądają następująco.
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
Zauważ, że ciągi danych z ctime()
są identyczne, chociaż wartości całkowite różnią się dla wszystkich trzech. Ponadto wartość całkowita for ctime
ma inny format niż for atime
i mtime
. atime
I mtime
wydają się być sekund od 1 stycznia 1970 roku, ale nie wiem co ctime
jest 5767254
.
Dzięki.
Poprawiony kod zgodnie z komentarzem @KamilCuk. Moja głupota i brzydki printf były przyczyną. Poniżej zmiany i nowe wyniki.
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 );
Nowe wyniki.
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
Odpowiedzi
Zasadniczo robisz:
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
}
Wszystkie asctime
(rozsądne implementacje) zapisują w tej samej pamięci i zwracają ten sam wskaźnik . Więc kiedy printf
jest wykonywany, po prostu wydrukuje zawartość tej samej pamięci. Zwróć uwagę, że kolejność obliczania argumentów funkcji nie ma ze sobą kolejności, ale kolejność obliczania wywołań funkcji jest nieokreślona. Każdy z możliwych wyników asctime
będzie ważny. Użyj asctime_r
lub zadzwoń jeden po drugim w oddzielnych printf
sekcjach.