我正在尝试打印 time_t 而不是在 Microsoft Visual Studio Project 中将其转换为 long int 并且它给了我意想不到的结果。源代码是
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
int main()
{
int a=1,b=2;
long int c=3;
time_t myTime;
time(&myTime);
printf("%d_%ld_%d_%ld",a,myTime,b,c);
printf("\n");
getchar();
return 0;
}
输出为 1_1389610399_0_2
。不过,这在我的 Linux 机器上运行良好。我知道 time_t 不应该像这样打印,但我不确定为什么?请告诉我如何调试此类问题?
编辑:鉴于 time_t
在 C 中被视为算术这一事实,我期望输出为 1_1389610399_2_3
。
最佳答案
I was expecting the output to be
1_1389610399_2_3
你的期望是错误的。不同的类型有不同的大小,当您通过可变参数传递“错误”类型时,这意味着接收者无法再在堆栈中的预期位置找到所有内容。这就是当格式代码与参数不匹配时行为未定义的原因:接收方读取的类型与调用方写入的类型不同。
0
你看到打印在你期望的地方 b
, 是 64 位 long long
的最高 32 位传递 time_t
时放置在堆栈上的值通过可变参数(在此实现中)。 %ld
格式化代码只占用了 myTime
值的前 4 个字节, 剩下的留给下一个格式化代码。
当它在 linux 上工作时,那是因为 time_t
是long
在该实现上,因此您的格式代码与您传递的类型相匹配。
有一种“通用”的方法可以打印任何有符号整数,即将其转换为intmax_t
。并使用格式化代码 %j
.不幸的是,你不能保证 time_t
是有符号类型,甚至是整数类型。所以这将更可移植,但仍然不是严格意义上的,因为 myTime
的值理论上可能不在intmax_t
的范围内根本。在 C++ 中你应该使用 std::cout << myTime;
,因为这样可以避免您需要知道 time_t
别名的实际类型(只要它不是任何类型的 char
即可)。
或者您可以使用 difftime
强制你的时间double
,您知道如何打印。或者你可以使用 gmtime
或 localtime
获得 segmentation 的日历时间,您知道如何使用 printf
打印其中的每个部分或 strftime
.
关于c++ - 在不强制转换的情况下打印 time_t 为 long int 会产生意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21089573/