如何正确使用 ctime() 来打印不同的时间戳

how to correctly use ctime() to print different time stamps

我原以为下面的代码应该打印不同的时间戳 t1 和 t2,但是结果显示 t1 和 t2 是相同的。我哪里弄错了?

#include<iostream>
#include<ctime>

using namespace std;

int main()
{
    time_t t1 = time(NULL);
    cout << "time now " << ctime(&t1) << endl;
    time_t t2 = t1 + 10000.0;
    cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;
}

结果:

time now Thu Apr 28 20:37:03 2016

time now Thu Apr 28 20:37:03 2016

 time later Thu Apr 28 20:37:03 2016

您的问题的答案可以在 the manual page for the ctime() function:

中找到

The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions.

ctime() returns 指向它使用的内部缓冲区的指针。每次调用时,它 returns 指向同一缓冲区的指针:

 cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;

对于这行代码,您的编译器生成的代码会调用 ctime() 两次,然后执行 << 运算符。但是在第二次调用 ctime() 时,它第二次覆盖了缓冲区,所以当 << 运算符格式化输出时,因为第一次调用 ctime() 的结果是相同的指针,并且它指向的缓冲区已被第二次调用 ctime() 覆盖,您将同时打印两次。

感谢您发布 Minimal, Complete, and Verifiable example

ctime 实际返回了什么?来自 cppreference:

Pointer to a static null-terminated character string holding the textual representation of date and time. The string may be shared between std::asctime and std::ctime, and may be overwritten on each invocation of any of those functions.

很可能在你的编译器上,较晚的 ctime() 首先被调用,然后是较新的 ctime(),然后两个 operator<<() 都被评估 - 它们发出相同的 char*。由于未指定的顺序,您的代码具有未定义的行为。在某些编译器上,它可以像您希望的那样工作!在你身上,它恰好没有。

如果将两个调用分开:

cout << "time now " << ctime(&t1) << endl;
cout << " time later " << ctime(&t2) <<endl;

您肯定会始终如一地看到不同的值。

引自N1570 7.27.3 时间转换函数:

Except for the strftime function, these functions each return a pointer to one of two types of static objects: a broken-down time structure or an array of char. Execution of any of the functions that return a pointer to one of these object types may overwrite the information in any object of the same type pointed to by the value returned from any previous call to any of them and the functions are not required to avoid data races with each other.

这表明从 ctime() 返回的内容指向的内容可以被另一个 ctime() 的调用覆盖,因此您必须复制结果才能在一个表达式中使用结果里面没有序列点。

试试这个:

#include<iostream>
#include<ctime>
#include<string>

using namespace std;

int main()
{
    time_t t1 = time(NULL);
    cout << "time now " << ctime(&t1) << endl;
    time_t t2 = t1 + 10000.0;
    string t1s = ctime(&t1);
    string t2s = ctime(&t2);
    cout << "time now " << t1s << endl << " time later " << t2s <<endl;
}