我有一个简单的C项目,我遇到了一个似乎无法解决的问题.注释掉这3行代码后,代码将产生以下正确结果:

1st Printing of Timestamp (UTC): 08/19/2023 15:04:48  (Unix Epoch time: 1692457488)
2nd Printing of Timestamp (UTC): 08/19/2023 15:04:48  (Unix Epoch time: 1692457488)

但是,如果我取消对这3行代码的注释,我会得到以下结果:

1st Printing of Timestamp (UTC): 08/19/2023 15:04:48  (Unix Epoch time: 1692457488)
2nd Printing of Timestamp (UTC): 08/19/2023 20:27:57  (Unix Epoch time: 1692457488)

其中"Second Print"产生present MM/DD/YYYY HH:MM:SS而不是正确的结果.Those 3 lines of code should have no effect在任何事情上-但他们确实这样做了,我看不到发生了什么.

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


int main()
{
    // Get a Unix epoch value
    long long timestamp_ms = 1692457488113;
    char formatted_time[50]; // only need 20 characters to hold "MM/DD/YYYY HH:MM:SS"

    // Convert Unix timestamp to "MM/DD/YYYY HH:MM:SS" format in UTC time
    time_t timestamp_seconds = (time_t)(timestamp_ms / 1000); // Convert milliseconds to seconds
    struct tm *timestamp_timeinfo = gmtime(&timestamp_seconds); // Use gmtime for UTC time

    // print result - should be 08/19/2023 15:04:48  (Unix Epoch time: 1692457488)
    strftime(formatted_time, sizeof(formatted_time), "%m/%d/%Y %H:%M:%S", timestamp_timeinfo);
    printf("1st Printing of Timestamp (UTC): %s  (Unix Epoch time: %lld)\n", formatted_time, timestamp_ms/1000);

       
/*    time_t current_utc_time; // Get current UTC time  grabbing variabluse I do nothing with (suspect gmtime memory leak)
      time(&current_utc_time);
      struct tm *current_timeinfo = gmtime(&current_utc_time);  
*/


    // print again, should be "08/19/2023 15:04:48  (Unix Epoch time: 1692457488)" but it is not
    strftime(formatted_time, sizeof(formatted_time), "%m/%d/%Y %H:%M:%S", timestamp_timeinfo);
    printf("2nd Printing of Timestamp (UTC): %s  (Unix Epoch time: %lld)\n", formatted_time, timestamp_ms/1000);

    return 0;
} 

推荐答案

至少是这些问题:

Not checking the return value

gmtime()time()可能返回NULL-1,指示失败.健壮的代码测试这一点.

一百零二

每次调用gmtime()localtime()都会返回指向相同struct tm的指针.当需要保留之前的值时,保存内容.


重写示例

int main(void) {
    long long timestamp_ms = 1692457488113;
    char formatted_time[50]; // only need 20 characters to hold "MM/DD/YYYY HH:MM:SS"

    time_t timestamp_seconds = (time_t)(timestamp_ms / 1000); // Convert milliseconds to seconds
    struct tm *timestamp_timeinfo = gmtime(&timestamp_seconds); // Use gmtime for UTC time
    if (timestamp_timeinfo == NULL) {
      fprintf(stderr, "Failure to convert\n");
      return -1;
    }
    struct tm t1 = *timestamp_timeinfo;

    // print result - should be 08/19/2023 15:04:48  (Unix Epoch time: 1692457488)
    if (0 == strftime(formatted_time, sizeof(formatted_time), "%m/%d/%Y %H:%M:%S", &t1)) {
      fprintf(stderr, "Failure strtime\n");
      return -1;
    }
    printf("1st Printing of Timestamp (UTC): %s  (Unix Epoch time: %lld)\n", formatted_time, timestamp_ms/1000);

       
    time_t current_utc_time; // Get current UTC time
    if (time(&current_utc_time) == -1) {
      fprintf(stderr, "Failure to convert\n");
      return -1;
    }
    struct tm *current_timeinfo = gmtime(&current_utc_time);  
    if (current_timeinfo == NULL) {
      fprintf(stderr, "Failure to convert\n");
      return -1;
    }

    // print again
    strftime(formatted_time, sizeof(formatted_time), "%m/%d/%Y %H:%M:%S", &t1);
    printf("2nd Printing of Timestamp (UTC): %s  (Unix Epoch time: %lld)\n", formatted_time, timestamp_ms/1000);

    return 0;
} 

次要问题:

char formatted_time[50]; // only need 20 characters to hold "MM/DD/YYYY HH:MM:SS"是危险的,行程代码判断器,因为访问的struct tm个成员是int,他们may的值只要是文本版本INT_MIN.如果年份是5位数呢?strftime()不假定成员在其主要范围内,代码的其余部分也不应假定.最好根据格式调整大小的缓冲区.

与其在缓冲空间上吝啬,不如慷慨一些.

#define TIME_FMT "%m/%d/%Y %H:%M:%S"
#define INT_LEN 11
#define FTIME_SIZE (6 * INT_LEN + sizeof(TIME_FMT))

char formatted_time[FTIME_SIZE];
strftime(formatted_time, sizeof(formatted_time), TIME_FMT, &t1);

C++相关问答推荐

如何将匿名VLA分配给指针?

识别和处理c中整数溢出的最佳方法?

Win32API Wizzard97 PropSheet_SetWizButton不工作

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

如何使用[BTStack]BLE发送大型(>;2kb)信息包

如何在C中打印包含扫描字符和整数的语句?

cairo 剪辑区域是否存在多个矩形?

S和查尔有什么不同[1]?

将数组插入数组

是否定义了此函数的行为?

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

用于计算位数和的递归C函数

在C中使用无符号整数模拟有符号整数

是否有单独的缓冲区用于读写库调用?

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

在C中使用字符串时是否不需要内存分配?

c如何传递对 struct 数组的引用,而不是设置 struct 的副本

C 程序不显示任何输出,但它接受 CS50 Lab1 的输入问题

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

我们可以在不违反标准的情况下向标准函数声明添加属性吗?