在C中将time_t转换为给定格式的字符串

时间:2016-11-08 18:56:48

标签: c string time posix

因此,作为作业的一部分,我们已经完成了这个骨架功能:

char *time2str(time_t time) {
    static char *str_fmt = "%02d/%02d/%4d %02d:%02d";
    char *time_s = ""; // appropriate string allocation here

    return time_s;
}

然而,我对C很陌生,并且正在努力解决我做错的问题(以及指针的工作方式)......我一直在努力使用localtime获得{ {1}}我可以使用它来访问我需要以给定格式添加到字符串的特定值。像这样:

struct

然而,无论我尝试做什么,我只是在编译时收到警告和错误(删除char *time2str(time_t time) { static char *str_fmt = "%02d/%02d/%4d %02d:%02d"; struct tm *info; info = localtime(&time); char *time_s = (str_fmt, info->tm_mday, info->tm_mon...etc...); return time_s; } 并使用str_fmt将格式放在time_s开头的引号中而不是info.tm_mday)。然而似乎没有任何效果,我找不到任何在线帮助我解决问题的方式。

有人可以帮忙吗?值得一提的是,我们使用MINIX系统调用在MINIX 3.2.1上进行此操作。

2 个答案:

答案 0 :(得分:2)

使用你给我们的东西,我认为函数应该是:

char *time2str(time_t time) {
    static char *str_fmt = "%02d/%02d/%4d %02d:%02d";

    // Convert to struct tm
    // localtime returns a pointer, so shallow copy to info
    struct tm info = *localtime(&time);

    // Allocate memory for ##/##/#### ##:##
    char *time_s = malloc(17);  // Space for 16 chars and eos
    if (NULL == time_s) {// Handle error.....}
    sprintf(time_s, str_fmt, info.tm_mon + 1, info.tm_mday, 1900 + info.tm_year,
           info.tm_hour, info.tm_min);

    return time_s;
}

答案 1 :(得分:0)

在C中管理字符串是一项棘手的任务。当出现意外情况时,多年成功的代码可能会失败。

考虑格式"%02d/%02d/%4d %02d:%02d"。这通常需要一个大小为16 + 1的数组(对于空字符)。这与Y2K bugs的编码类型相同,因为在9999年之后需要更多的空间。考虑一个允许time_t表示远期未来的时间并尝试形成日期/的系统基于其最大值的时间字符串 - >缓冲区溢出。

相反,允许struct tm中的所有潜在值并提供一个宽大的临时缓冲区。然后分配。

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

// Max length needed for a `int` as decimal text 
#define INT_STR_LEN (sizeof(int)*CHAR_BIT/3 + 2)

#define TIME2STR_FMT "%02d/%02d/%04d %02d:%02d"
// Worst case size - and them some
#define TIME2STR_SZ (sizeof TIME2STR_FMT + 5*INT_STR_LEN)

char *time2str(time_t time) {

  struct tm *info = localtime(&time);
  if (info == NULL) return NULL;

  char buf[TIME2STR_SZ];
  int n = snprintf(buf, sizeof buf, TIME2STR_FMT, info->tm_mon + 1, info->tm_mday,
      info->tm_year + 1900, info->tm_hour, info->tm_min);
  if (n < 0 || n >= sizeof buf) return NULL;

  // Allocate and copy
  size_t sz = strlen(buf) + 1;
  char *time_s = malloc(sz);
  if (time_s) {
    memcpy(time_s, buf, sz);
  }

  return time_s;
}

int main(void) {
  time_t t;
  puts(time2str(time(&t)));
  return 0;
}