C++ 打印时间\u t为长整型而不强制转换会产生意外的行为

C++ 打印时间\u t为长整型而不强制转换会产生意外的行为,c++,c,datetime,C++,C,Datetime,我试图在Microsoft Visual Studio项目中打印时间,但没有将其转换为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;

我试图在Microsoft Visual Studio项目中打印时间,但没有将其转换为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;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
INTA=1,b=2;
长整数c=3;
时间是我的时间;
时间(&myTime);
printf(“%d\%ld\%d\%ld”,a,myTime,b,c);
printf(“\n”);
getchar();
返回0;
}
输出为
1\u 1389610399\u 0\u 2
。这在我的linux机器上运行得很好。我知道时间不应该像这样打印,但我不知道为什么?请告诉我如何调试这样的问题


编辑:鉴于
时间t
在C中被视为算术运算,我希望输出是
1\u 1389610399\u 2\u 3

谁说
时间t
长的?它可以是任何算术类型。
使用时必须显式将其转换为某个定义的类型
printf

使用
ostream
,并避免此类问题。

要以安全的方式显示其(
time\t
)内容,应首先使用(即
gmtime
将其转换为
struct tm
,然后使用其中一个字段或使用
strftime
将其进一步转换为字符串

我希望输出是
1\u1389610399\u2\u3

你以为这是错误的。不同的类型具有不同的大小,当您通过varargs传递“错误”类型时,这意味着接收器无法再在预期位置找到堆栈上的所有内容。这就是为什么当格式化代码与参数不匹配时,行为是未定义的:接收方读取的类型与调用方写入的类型不同

您看到的打印出来的
0
在您期望的
b
位置,是64位
long
值中最重要的32位,当您通过varargs传递
time\u t
时,该值放置在堆栈上(在此实现中)。
%ld
格式化代码只占用了
myTime
值的前4个字节,其余的由下一个格式化代码占用

当它在linux上工作时,这是因为
time\u t
在该实现上是
long
,因此您的格式代码与您传递的类型匹配

打印任何有符号整数有一种“通用”方法,即将其转换为
intmax\u t
,并使用格式化代码
%j
。不幸的是,您不能保证
time\u t
是有符号类型,甚至不能保证它是整数类型。因此,这将更便于移植,但严格来说仍然不是这样,因为理论上,
myTime
的值可能根本不在
intmax\t
的范围内。在C++中,你应该使用<代码> STD::CUT< P>时间()函数返回“自UTC,1月1日1970时起”的秒数。 资料来源:

因此,您得到的值(1389610399)相当不错,如下所示:

1389610399/60(=分钟)/60(=小时)/24(=天)/365~44年,这似乎相当合理

例如,如果您想要获得天数,那么将时间值除以3600。 如果要获取日期,请参考其他函数,如localtime()或gmtime()-后者以UTC格式返回日期和时间。请参阅以下提供的示例:

希望有帮助! 格里茨,
Michael

要使用格式字符串打印64位整数,必须使用
%I64d
而不是
%ld

但是,要小心,因为时间的类型取决于硬件的位。

我不明白你在问什么。您知道打印错误,但不知道为什么它没有达到预期效果?您想要什么输出?C中的时间类型被认为是算术类型。因此,预期的输出应该类似于1_1389610399_2_3。我不明白为什么输出是这样来的。@Abhishek:从你的结果来看(我没有检查文档)
time\u t
在Windows上是
long
,这是合理的。当你将错误的类型作为varargs传递时,事情就出了问题。为什么不应该这样打印时间?谁告诉你的?虽然
time\u t
可能是其他东西(它的实现是指定的),但在它是整数的平台上,它确实可以这样打印。它不会告诉你任何事情,除了它是一个很大的数字,但除此之外,它是好的。您只需要小心使用正确的格式代码输出它(或者使用C++输出操作符<代码> @ RAMYABEL:我认为这是不对的。因为从回答中我认为它是平台相关的。但是我如何不去解释它会影响后面的B的参数?我不理解这个。”AbHeHek,因为你把错误的类型传递给VARYARGS。这会导致VAR-ARGS机制变成UNS。与您的输入同步。(通常的机制包括将提取元素的大小添加到
char*
以获取下一个元素的地址。)您必须将接收程序期望的确切类型传递给var args。谢谢@James,我现在已经很清楚了。我将更深入地研究printf实现和var args机制,以获得更深入的了解。谢谢您的详细回答@steve,但不应该根据此逻辑,printf(“%d_%ld_%d”,a,b,c);应该将输出设置为1_2_0,但将其设置为1_2_3。@Abhishek:no.
int
long
在Windows上大小相同。当然,这仍然是未定义的行为。