我期待下面的代碼應該打印不同的時間戳t1和t2,但結果顯示t1和t2是相同的。我在哪裏犯了錯誤?如何正確使用ctime()打印不同的時間戳
結果:
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
我期待下面的代碼應該打印不同的時間戳t1和t2,但結果顯示t1和t2是相同的。我在哪裏犯了錯誤?如何正確使用ctime()打印不同的時間戳
結果:
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發現:
返回值指向一個靜態分配的字符串可能 的後續調用覆蓋到任何日期和時間 函數。
ctime()返回一個指向它使用的內部緩衝區的指針。每次它叫時,它返回一個指向同一緩衝區:
cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;
對於此行的代碼,你的編譯器生成的代碼調用ctime()
兩次,然後執行<<
操作。但在第二次調用ctime()
時,它第二次覆蓋了緩衝區,所以當<<
運算符格式化輸出時,因爲第一次調用ctime()
的結果是相同的指針,並且它指向的緩衝區已被覆蓋通過第二次電話ctime()
,您可以同時打印兩次。
什麼是ctime
實際返回?從cppreference:
指向包含日期和時間文本表示的靜態空終止字符串的指針。 字符串可以在
std::asctime
和std::ctime
之間共享,並且可以在對這些函數中的任何函數的每次調用時被覆蓋。
它可能工作的是你的編譯器,後來ctime()
被首先調用,那麼更新ctime()
,那麼這兩個operator<<()
小號得到評估 - 這發出相同char*
。由於未指定的順序,您的代碼具有未定義的行爲。在一些編譯器上,它可以像你期望的那樣工作!在你的情況下,情況並非如此。
如果分離出兩個電話:
cout << "time now " << ctime(&t1) << endl;
cout << " time later " << ctime(&t2) <<endl;
你肯定會和不斷地看到不同的值。
報價從N1570 7.27.3時間轉換功能:
除strftime函數,這些函數返回一個指向兩個 類型的靜態對象中的一個:一個破碎下降時間結構或字符數組。執行 任何返回指向其中一個對象類型的函數的任何函數都可能會覆蓋以前調用任何對象時返回的值所指向的同一類型的任何對象中的信息,並且這些函數不是必需的以避免數據與 彼此競爭。
這表明,通過取之於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;
}
PS:根據下面的精彩解答,這個問題應該與雙方的ctime()函數,作品和順序編譯器如何評價COUT參數。對於後者,請參考http://stackoverflow.com/questions/12960241/explain-the-order-of-evalution-in-printf舉例 – daydayup