理解对ctime()的连续调用

4
我有一个关于glibc ctime()如何工作的问题。
下面是我的代码片段:
#include    <stdio.h>
#include    <time.h>
#include    <stdlib.h>


int main (int argc,char** argv)
{
    int ret=EXIT_SUCCESS;

    time_t tm1;
    time_t tm2;


    tm1 = time(NULL);
    tm2 = tm1 + 60; // 60 seconds later


    puts("1st method-------");
    printf("tm1 = %stm2 = %s",ctime(&tm1),ctime(&tm2));


    puts("2nd method-------");
        printf("tm1 = %s",ctime(&tm1));
    printf("tm2 = %s",ctime(&tm2));

    return(ret);
}

I got:

1st method-------
tm1 = Sat Jan 14 01:13:28 2012
tm2 = Sat Jan 14 01:13:28 2012
2nd method-------
tm1 = Sat Jan 14 01:13:28 2012
tm2 = Sat Jan 14 01:14:28 2012

正如您所看到的,第一种方法中两个时间都有相同的值,这是不正确的。在第二种方法中,我获得了正确的值。

我知道ctime()将这些字符串放在静态缓冲区中,并且要覆盖它,我们需要连续调用ctime()。

问题:在第一种方法中我没有进行连续调用吗?

谢谢您的回复。

1个回答

3
您已经提供了解决问题所需的所有信息。
第二种方法按预期工作:调用ctime,填充缓冲区并打印结果;然后重复此过程。因此,您会得到两个不同的时间打印出来。
对于第一种方法,顺序不同:先调用ctime,然后再次调用,只有在这之后才会打印结果。每次调用ctime的结果都相同,至少就printf而言:静态缓冲区的地址。但是该缓冲区的内容已被每次调用更改,并且由于printf在两个ctime调用完成之前不查看缓冲区,因此最终会将新内容输出两次。
所以,在第一种方法中您确实进行了两次调用,只是第一次调用的结果在打印之前被覆盖了。

谢谢,但正如你所看到的,它保留了旧的(tm1)而不是新的(tm2)结果,它不会覆盖缓冲区,除非在ctime(&tm1)之前处理ctime(&tm2)。 - hadibou
@Hadi:你似乎不理解的是,参数是以相反的顺序推入的。当ctime语句都是printf的参数时,带有tm1的那个会被最后调用,而不是第一个。Scott说得对。 - boatcoder
@Mark0978 在 C 中,函数参数的求值顺序没有定义。你可能已经知道了这一点。 https://dev59.com/ZnRC5IYBdhLWcg3wMeLg - VoidPointer
@VoidPointer 说得好。虽然我从未遇到过不这样做的实现。 - boatcoder
1
为了进行连续调用,Unix 系统使用 ctime_r 函数,Windows 系统使用 ctime_s 函数。(供您参考) - anilbey

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