【问题标题】:Use struct tm to print a specific date and strftime使用 struct tm 打印特定日期和 strftime
【发布时间】:2018-09-25 16:26:38
【问题描述】:

所以我需要专门使用 struct tm 来打印我的生日,我成功地做到了。但是,我还需要使用 strftime() 以不同的格式打印它。 这就是我遇到问题的地方,因为 strftime() 只能识别指针参数。

#include <stdio.h>
#include <time.h>

int main(){

    struct tm str_bday;
    time_t time_bday;
    char buffer[15];

    str_bday.tm_year = 1994 - 1900 ;
    str_bday.tm_mon = 7 - 1;
    str_bday.tm_mday = 30;
    str_bday.tm_hour = 12;
    str_bday.tm_min = 53;
    time_bday = mktime(&str_bday);
    if(time_bday == (time_t)-1)
        fprintf(stdout,"error\n");
    else
        {
        fprintf(stdout,"My birthday in second is: %ld \n",time_bday);
        fprintf(stdout,"My birthday is: %s\n", ctime(&time_bday));//Wed July 22 12:53:00 1998
        strftime(buffer,15,"%d/%m/%Y",time_bday);
        fprintf(stdout,"My birthday in D/M/Y format is %s",buffer);
        }
    return 0;
}

错误是:

Error:  passing argument 4 of ‘strftime’ makes pointer from integer without a cast

    expected ‘const struct tm * restrict’ but argument is of type ‘time_t’

谁能告诉我如何解决它?

编辑:将 time_bday 更改为 &str_bday 有效!但是现在程序每次运行时都会输出随机时间和日期。

编辑:我使用了 puts(buffer),而不是 strftime() 之后的 fprintf(),并且效果很好。另外,将缓冲区 [15] 更改为缓冲区 [30],因为我有小时、分钟和秒。

【问题讨论】:

  • 好吧,既然它需要一个struct tm*,您是否尝试过将一个指向struct tm 的指针传递给它?尝试传递 &amp;str_bday 而不是 time_bday
  • @FelixGuo 哦,是的,谢谢!但是现在,每次我运行这个程序时,它都会显示不同的日期和时间
  • 不确定为什么会得到不一致的结果(使用哪个输出)?但是,您并没有设置str_bday 的所有字段。您可以尝试使用 C99 样式的语法 const struct tm str_bday = { .tm_year = 98, .tm_mon = 7, /* ... */ }; 进行设置,或者如果这对 ctime() 工作来说足够正确,您可以从 gmtime() 获得往返转换。
  • 我相信你的实际生日是完全不同的日期。不建议在互联网上发布您的真实信息(尽管在关于 SO 的问题中包含更糟糕的信息)。

标签: c pointers struct time-t


【解决方案1】:

通过查看strftime 的原型,您可以看到您应该将const struct tm* 作为最后一个参数传递:

size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr);

在您的情况下,这将是 &amp;str_bday 而不是 time_bday

struct tm 有几个字段您没有初始化,因此采用不确定的值,导致您看到时间跳跃。在插入值之前,您可以使用 struct tm str_bday = {0} 将所有字段初始化为零。

【讨论】:

  • 由于str_bday是编译时已知的常量数据,我推荐static const struct str_bday = { .tm_year = 98, .tm_month = 7, /* ... */ };
  • 如果做不到这一点,具有static 存储类的结构将被初始化为所有位为零,因此至少这会产生可重现的结果。保证零初始化自动存储的可移植方式是memset(),保证零初始化动态存储的方式是calloc()
【解决方案2】:

mktime(&amp;str_bday); 在计算time_t 时取决于struct tm 的各个成员1

首先将成员初始化为0 是一种很好的做法。

// struct tm str_bday;
struct tm str_bday = { 0 };

OP 的代码无法初始化某些成员,例如 tm_sec,这肯定会导致错误的结果。

然而,初始化所有相关成员也很重要。 OP的代码没有分配tm_isdststruct tm str_bday = { 0 },这就像

str_bday.tm_isdst = 0; // Set time stamp to **standard** time.

问题在于,在OP's school 中,该日期的夏令时设置肯定是夏令时

// add
str_bday.tm_isdst = -1; // Let mktime() determine DST setting
// or if one knowns it is daylight time.
str_bday.tm_isdst = 1; // Set time stamp to **daylight** time.
// or if one knowns it is standard time.
str_bday.tm_isdst = 0; // Set time stamp to **standard** time.

ctime(&amp;time_bday)的打印错误应该很明显

// My birthday is: Sat Jul 30 13:53:00 1994
My birthday is: Sat Jul 30 12:53:00 1994

更正的代码

#include <locale.h>
#include <time.h>
int main() {

  struct tm str_bday = { 0 };
  time_t time_bday;
  char buffer[15];

  str_bday.tm_year = 1994 - 1900;
  str_bday.tm_mon = 7 - 1;
  str_bday.tm_mday = 30;
  str_bday.tm_hour = 12;
  str_bday.tm_min = 53;
  str_bday.tm_isdst = -1;
  time_bday = mktime(&str_bday);

  strftime(buffer, sizeof buffer, "%d/%m/%Y", &str_bday);
  if (time_bday == (time_t) -1) {
    fprintf(stdout, "error\n");
  } else {
    // Do not assume `long`.  Better to cast to a wide type. 
    fprintf(stdout, "My birthday in second is: %lld \n", (long long) time_bday);
    fprintf(stdout, "My birthday is: %s", ctime(&time_bday));
    // strftime(buffer,15,"%d/%m/%Y",time_bday);
    strftime(buffer, sizeof buffer, "%d/%m/%Y", &str_bday);
    fprintf(stdout, "My birthday in D/M/Y format is %s\n", buffer);
  }
  return 0;
}

1 成员 tm_wdaytm_yday 不参与计算,但会更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多