C++ 打印时间\u t为长整型而不强制转换会产生意外的行为
我试图在Microsoft Visual Studio项目中打印时间,但没有将其转换为long int,这给了我意想不到的结果。源代码是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;
#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上大小相同。当然,这仍然是未定义的行为。