如何正确使用 ctime() 打印不同的时间戳
Posted
技术标签:
【中文标题】如何正确使用 ctime() 打印不同的时间戳【英文标题】:how to correctly use ctime() to print different time stamps 【发布时间】:2016-08-23 23:41:13 【问题描述】:我原以为下面的代码应该打印不同的时间戳 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
【问题讨论】:
PS:根据下面的精彩答案,问题应该与 ctime() 函数的工作方式和编译器评估 cout 参数的顺序有关。后者可以参考***.com/questions/12960241/…的例子 【参考方案1】:你的问题的答案可以在the manual page for the ctime() function找到:
返回值指向一个静态分配的字符串,它可能 被后续调用任何日期和时间覆盖 功能。
ctime() 返回一个指向它使用的内部缓冲区的指针。每次调用它都会返回一个指向同一个缓冲区的指针:
cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;
对于这行代码,您的编译器生成的代码调用ctime()
两次,然后执行<<
运算符。但是在第二次调用ctime()
时,它第二次覆盖了缓冲区,所以当<<
运算符格式化输出时,因为第一次调用ctime()
的结果是同一个指针,而缓冲区它指向的已被第二次调用ctime()
覆盖,您会得到相同的时间打印两次。
感谢您发布Minimal, Complete, and Verifiable example。
【讨论】:
【参考方案2】:ctime
实际返回的是什么?来自cppreference:
指向以空字符结尾的静态字符串的指针,该字符串包含日期和时间的文本表示。 字符串可以在
std::asctime
和std::ctime
之间共享,并且可以在每次调用这些函数时被覆盖。
很可能在您的编译器上,先调用较晚的ctime()
,然后调用较新的ctime()
,然后评估两个operator<<()
——它们发出相同的char*
。由于未指定顺序,您的代码具有未定义的行为。在某些编译器上,它可以像您希望的那样工作!在你的身上,它恰好不是。
如果你把这两个电话分开:
cout << "time now " << ctime(&t1) << endl;
cout << " time later " << ctime(&t2) <<endl;
您肯定会始终如一地看到不同的价值观。
【讨论】:
【参考方案3】:引自N1570 7.27.3 时间转换函数:
除了 strftime 函数,这些函数都返回一个指向两个函数之一的指针 静态对象类型:分解的时间结构或字符数组。执行 返回指向这些对象类型之一的指针的任何函数都可能覆盖 由 any 返回的值所指向的任何相同类型的对象中的信息 以前调用它们中的任何一个,并且不需要这些函数来避免与 彼此。
这表明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;
【讨论】:
以上是关于如何正确使用 ctime() 打印不同的时间戳的主要内容,如果未能解决你的问题,请参考以下文章