asctime()奇怪的行为

时间:2014-08-21 09:44:23

标签: c time.h



我有以下代码。

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

int main(int argc, char** argv) { 
  time_t t1, t2;
  time(&t1);/* set current time to t1 */

  struct tm T1, T2;
  int i;       
  scanf("%d", &i); /* for delaying */
  time(&t2); /* set current time to t2 */

  T1 = *(struct tm*)localtime(&t1);
  T2 = *(struct tm*)localtime(&t2);

  printf("%s%s", asctime(&T1), asctime(&T2)); /* display them */
}

基本上,我想在t1上获得当前时间,然后(在等待i被读取引起的延迟之后)获得t2上的当前时间。 t1和t2不同,T1.tm_sec和T2.tm_sec也不同,但printf显示完全相同的日期(对应于T1的日期)。我知道在内部,asctime(http://www.cplusplus.com/reference/ctime/asctime/?kw=asctime)使用静态指针,但我尝试了一个较小的示例程序,其中一个函数返回一个静态字符指针并且它们有效。

char* test(int t) {
    static char result[10];
    sprintf(result, "%d", t);

    return result;
}

,我就像这样使用它

printf("%s ", test(5));
printf("%s ", test(7));

并且它有效(打印的字符串不同)。

所以我猜它不能从那里开始。我还复制了asctime代码(来自cplusplus)并在函数中放入了一些printfs,我注意到sprintf语句后结果变量得到了正确的更新。

那么printf会显示相同的日期会发生什么?

来自cplusplus.com的asctime代码

char* asctime(const struct tm *timeptr)
{
   static const char wday_name[][4] = {
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
   };
  static const char mon_name[][4] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
  static char result[26];
  sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
    wday_name[timeptr->tm_wday],
    mon_name[timeptr->tm_mon],
    timeptr->tm_mday, timeptr->tm_hour,
    timeptr->tm_min, timeptr->tm_sec,
    1900 + timeptr->tm_year);
    return result;
}

2 个答案:

答案 0 :(得分:1)

问题是,使用test功能的测试检查了除asctime之外的其他方案。使用test

printf("%s ", test(5));
printf("%s ", test(7));

您有两个单独的函数调用,而asctime则有

printf("%s%s", asctime(&T1), asctime(&T2)); /* display them */

在一个函数中将两个调用作为参数。在调用printf函数之前计算参数,因此asctime的错误行为是可见的 - 对asctime的一个调用会覆盖另一个的结果。将asctime的结果复制到某处,然后再次调用它,以便更好地使用asctime_r

答案 1 :(得分:1)

有以下不同之处:

printf("%s%s", asctime(&T1), asctime(&T2));

printf("%s ", test(5));
printf("%s ", test(7));

第一个(也导致你定义为&#34;奇怪的&#34;行为)使用静态内存位置来存储字符串。第二个调用会覆盖第一个调用的结果。

在第二个示例中,您实际使用第一个调用的结果,然后再次调用该函数。为了保存这两个结果,您可以执行以下操作:

printf("%s%s", strdup(asctime(&T1)), strdup(asctime(&T2)));

哪个会分配副本并将结果存储在那里。更好的是这样的:

char *result1 = strdup(asctime(&T1)), *result2 = strdup(asctime(&T2));

printf("%s%s", result1, result2);

free(result1);
free(result2);