使用HH:MM:SS格式将时间转换为字符串(C编程)

9

我需要将当前时间以“HH:MM:SS”格式获取并存储在字符数组(字符串)中,以便稍后可以通过printf("%s", timeString);输出结果。

对于timevaltime_t类型,我感到相当困惑,希望能够得到解释。

编辑:我尝试使用strftime等函数,它有点起作用。这是我的代码:

time_t current_time;
struct tm * time_info;
char timeString[8];

time(&current_time);
time_info = localtime(&current_time);

strftime(timeString, 8, "%H:%M:%S", time_info);
puts(timeString);

但是输出结果是这样的:"13:49:53a??J`aS?"。
最后的"a??J`aS?"是什么情况?
3个回答

14

从这段代码中你得到的是垃圾数据:

time_t current_time;
struct tm * time_info;
char timeString[8];

time(&current_time);
time_info = localtime(&current_time);

strftime(timeString, 8, "%H:%M:%S", time_info);
puts(timeString);
因为您没有为该字符串留出空间来存放空终止符(\0),所以当打印该字符串时,它不知道其末尾在哪里,并将下一位内存中的随机值解释为该字符串的一部分。请更改为以下内容:
time_t current_time;
struct tm * time_info;
char timeString[9];  // space for "HH:MM:SS\0"

time(&current_time);
time_info = localtime(&current_time);

strftime(timeString, sizeof(timeString), "%H:%M:%S", time_info);
puts(timeString);

并且它会正确工作,因为 strftime() 将有足够的空间添加一个\0。请注意,我使用 sizeof(array) 来避免在两个地方都忘记更改数字的风险。


1
我通常采取悲观的方法并过度分配缓冲区大小。例如,我会声明 timeString [] 为20个或更多字符。内存很便宜,我们只谈论几个额外的字节。当您稍后决定更改格式字符串但忘记更新缓冲区长度时,这可以为您节省时间。 - David R Tribble
+1 用 sizeof() 让编译器传递数组的大小。 - Randall Cook

6

请看strftime函数,它允许您按照自己的格式将时间写入字符数组中。


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

/* get seconds since the Epoch */
time_t secs = time(0);

/* convert to localtime */
struct tm *local = localtime(&secs);

/* and set the string */
sprintf(timeString, "%02d:%02d:%02d", local->tm_hour, local->tm_min, local->tm_sec);

处理时间(指墙钟时间,而不是进程/线程时间)的重要类型为time_tstruct tm。您可以进行一些工作来在两者之间进行转换,但必须注意本地时间与UTC时间之间的区别。
请查阅描述<time.h>的说明,尝试使用其中的函数,直到您完全理解C中的时间概念。
再次提醒,要注意UTC时间和本地时间之间的区别。

我们难道不应该尽力避免使用本质上不安全的sprintf()函数,以免扩散其使用吗? - Randall Cook
我有点同意...但是...不在上面的代码片段中...我们不应该尽力避免使用本质上不安全的整数加法吗? - pmg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接