【问题标题】:ctime functions in C returns same string for differing values of atime, mtime, and ctime?C 中的 ctime 函数为 atime、mtime 和 ctime 的不同值返回相同的字符串?
【发布时间】:2021-03-10 20:13:44
【问题描述】:

在 minGW-W64 中使用 stat() 函数及其返回的结构时,这里是 info,为什么 ctime 会为 info.st_atimemtimectime 返回完全相同的字符串,即使它们的整数值不同?

如果使用localtime单独获取每个时间分量,结果会有所不同,显得准确;也就是说,它们与我观察到的文件夹中的日期相匹配。

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

三年多以前有人问过类似的question,但没有答案。

有谁知道为什么以及是否有任何关于 minGW-W64 日期的文档?

谢谢。


这是完整的代码示例。这是一个丑陋的 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;
}

一个文件的结果如下所示。

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

请注意,来自ctime() 的数据字符串是相同的,尽管这三个字符串的整数值不同。此外,ctime 的整数值与atimemtime 的格式不同。 atimemtime 似乎是自 1970 年 1 月 1 日以来的秒数,但我不知道 ctime 是什么 5767254

谢谢。


根据@KamilCuk 的评论修复了代码。我的愚蠢和丑陋的 printf 是原因。以下更改和新结果。

  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 );

新结果。

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

【问题讨论】:

  • 你为什么在参数列表中多次调用localtime?为什么不调用一次呢?这不是未定义的行为吗?您的代码是否取决于参数评估的特定顺序? ctimelocaltime 都返回指向静态分配内存的指针,每次都相同指针。当然,一切都将是一样的。
  • @KamilCuk 我按照您的指示更改了代码并在问题中显示。现在所有的结果看起来都很好。我只是很愚蠢,不明白我在做什么。谢谢。
  • 对不起,当问题是我不理解和愚蠢的时候问这样的问题。我应该删除它吗?
  • @KamilCuk 好的,谢谢。我从来没有去掉不正确的代码,只是在下面的一个块中添加了更改。
  • @DavidC.Rankin 非常感谢您的帮助。那我就不删了。我可以在 JavaScript 中解决 C 中无法解决的问题。我很高兴学习它。

标签: c ctime


【解决方案1】:

你基本上是在做:

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
}

所有asctime(合理的实现)写入相同的内存并返回相同的指针。因此,当printf 被执行时,它只会打印相同内存的内容。请注意,函数的参数order of evaluation 彼此之间没有顺序,但函数调用的评估顺序是不确定的。 asctime 的任何一个可能结果都是有效的。使用asctime_r 或在单独的printfs 中依次调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 2011-06-02
    • 2013-11-01
    • 1970-01-01
    • 2013-01-12
    相关资源
    最近更新 更多