【发布时间】:2019-05-29 10:38:06
【问题描述】:
我正在使用 C 中的代码,它使用以下内容从服务器获取时间:
(这是一个很短的版本,代码的其他部分和函数使用time、ftime和localtime函数来获取时间)。
struct tm *stiempo;
long ltiempo;
FILE * arch2;
int main()
{
print_error_time();
}
void print_error_time()
{
time (<iempo);
stiempo = localtime (<iempo);
fprintf (arch2, "%02.2ld/%02.2ld/%02.2ld, \t %02.2ld:%02.2ld:%02.2ld", stiempo->tm_mday, (stiempo->tm_mon + 1), (stiempo->tm_year + 1900), stiempo->tm_hour, stiempo->tm_min, stiempo->tm_sec);
}
有时它工作得很好,但有时,当时间打印到文件中时,我会得到这样的东西:
21/08/2018, 15:48:7956003943165722682
21/08/2018, 15:50:7956003943165722667
21/08/2018, 15:51:7956003943165722649
有谁知道是什么导致了这种行为,或者什么会影响使它们返回这些值的时间函数?
【问题讨论】:
-
arch2FILE指针未指向任何FILE对象。 -
您在
fprintf()中使用了错误的格式说明符,这是未定义的行为。 -
struct tm中的大多数字段不是long,而是int,并且在64 位机器上使用%ld打印它们会导致不可预知的行为。您可以使用%.2d或%02d来获得您想要的结果(可能),但也许您应该在一年中使用 4 而不是 2(尽管它不会对 2 造成损害)。在 32 位机器上,您可以使用sizeof(int) == sizeof(long)。此外,出于同样的原因,Win64 可能没问题。 -
这可能是唯一的原因吗?我正在尝试在另一台机器上复制该错误,但我不能。我正在运行相同的代码,它以应有的方式打印时间,甚至使用
%ld打印 -
@Fausto:未定义行为的问题在于允许代码按预期工作和按预期工作,两者都是正确的,因为官方要求未定义。您可以看到它在机器 A 上运行而在机器 B 上失败的一种方法是机器 A 是 32 位而机器 B 是 64 位。如果工作机器是 Windows 64 位而非工作机器不是,您也可能会遇到问题。如果一台机器上的 CPU 是 little-endian 而另一台机器上的 CPU 是 big-endian,您可能会遇到问题。你还没有确定你的两台机器有多相似。