C语言 实现定义类型的格式说明符,如 time_t
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18839043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Format specifiers for implementation-defined types like time_t
提问by effervescent-phantom
I want to make my code more platform-/implementation-independent. I don't know what a time_twill be implemented as on the platform when the code is being compiled. How do I know the type of tto determine what format specifier to use?
我想让我的代码更加独立于平台/实现。我不知道time_t在编译代码时会在平台上实现什么。我如何知道t确定要使用的格式说明符的类型?
...
time_t t = time(NULL);
printf("%s", t);
...
采纳答案by Eric Postpischil
Generally, the way to display the value of a time_tis to break down its components to a struct tmusing gmtimeor localtimeand display those or convert them as desired with strftime, or ctimeto go directly from time_tto a string showing local time.
通常,显示 a 的值的方法time_t是将其组件分解为struct tm使用gmtimeorlocaltime并显示这些或根据需要使用 将它们转换strftime,或者ctime直接从time_t显示本地时间的字符串转到。
If you want to see the raw value for some purpose, the C standard specifies that time_tis real, which means it is integer or floating-point (C 2011 (N1570) 6.2.5 17). Therefore, you should be able to convert it to doubleand print that. There is some possibility that time_tcan represent values that doublecannot, so you might have to guard against that if you want to take care regarding exotic implementations. Since difftimereturns the difference of two time_tobjects as a double, it seems C does not truly support time_twith more precision than a double.
如果您想出于某种目的查看原始值,C 标准指定time_t为real,这意味着它是整数或浮点数 (C 2011 (N1570) 6.2.5 17)。因此,您应该能够将其转换为double并打印出来。有一些可能性time_t可以表示不能表示的值double,因此如果您想注意异国情调的实现,则可能必须防范这种情况。由于difftime将两个time_t对象的差异作为 a返回double,因此 C 似乎并不真正支持time_t比 a 更精确的支持double。
回答by Keith Thompson
Usually you can use a cast to convert the operand to some type for which you know the right format.
通常,您可以使用强制转换将操作数转换为您知道正确格式的某种类型。
Your proposed solution:
您提出的解决方案:
time_t t = time(NULL);
printf("%s", t);
clearly will notwork, since time_tis a numeric type, not char*.
显然将无法工作,因为time_t是数字类型,而不是char*。
We know, in general, that time_tis an arithmetic type. Something like this:
我们知道,一般来说,这time_t是一种算术类型。像这样的东西:
printf("%ld\n", (long)t);
is likely to work on most systems. It can fail (a) if time_tis an unsigned type no wider than unsigned longand the current value of texceeds LONG_MAX, or (b) if time_tis a floating-point type.
可能适用于大多数系统。它可能会失败(a)如果time_t是不大于 的无符号类型unsigned long并且当前值t超过LONG_MAX,或者(b)如果time_t是浮点类型。
If you have C99 support, you can use long long, which is a little better:
如果你有 C99 支持,你可以使用long long,这会好一点:
printf("%lld\n", (long long)t);
If you really want to go overboard with portability, you can detect what kind of type time_tis:
如果你真的想过度携带便携性,你可以检测哪种类型time_t是:
if ((time_t)-1 > 0) {
// time_t is an unsigned type
printf("%ju\n", (uintmax_t)t);
}
else if ((time_t)1 / 2 > 0) {
// time_t is a signed integer type
printf("%jd\n", (intmax_t)t);
}
else {
// time_t is a floating-point type (I've never seen this)
printf("%Lg\n", (long double)t);
}
You might want to tweak the %Lgformat to something like %Lfor %.10Lf, depending on what output format you want.
您可能希望将%Lg格式调整为%Lf或 之类的内容%.10Lf,具体取决于您想要的输出格式。
Again, this assumes C99 support -- and you'll need #include <stdint.h>to make uintmax_tand intmax_tvisible.
同样,这假设 C99 支持 - 您需要#include <stdint.h>制作uintmax_t和intmax_t可见。
time_tand clock_tare a bit unusual, in that the standard says onlythat they're arithmetic type capable of representing times. (In principle they could be complex types, but I'd say ignoring that possibility is worth the risk.)
time_t并且clock_t有点不寻常,因为标准只说它们是能够表示时间的算术类型。(原则上它们可能是复杂类型,但我认为忽略这种可能性是值得的。)
In most other cases, you'll probably know whether a given type is signed, unsigned, or floating-point, and you can just convert to the widest type of that kind.
在大多数其他情况下,您可能会知道给定类型是有符号、无符号还是浮点类型,并且您可以只转换为该类型中最宽的类型。
Note that if you don't know how time_tis represented, you probably won't understand the output of the printf(such as 1379375215) either -- unless your goal is to figure that out.
请注意,如果您不知道如何time_t表示,您可能也不会理解printf(例如1379375215)的输出——除非您的目标是弄清楚这一点。
(If you were programming in C++ rather than C, std::cout << t << "\n";would automatically use the correct overloaded operator<<.)
(如果您使用 C++ 而不是 C 进行编程,std::cout << t << "\n";将自动使用正确的重载operator<<.)
If you want human-readableoutput (like Mon 2013-09-16 16:46:55 PDT), you'll want to use one of the conversion functions declared in <time.h>, such as asctime()or strftime().
如果您想要人类可读的输出(例如Mon 2013-09-16 16:46:55 PDT),您需要使用 中声明的转换函数之一<time.h>,例如asctime()或strftime()。
回答by chus
You can use difftime()to obtain a double:
您可以使用difftime()来获取double:
time_t t = time(NULL);
printf("seconds 1970->now: %.f\n", difftime(t, (time_t) 0));
It is simple and I think it is portable.
它很简单,我认为它是便携的。
回答by Jonathan Leffler
The C standard says time_twill be a 'real type' (meaning an integer type or a floating point type, though in practice it is always an integer type).
C 标准说time_t将是“真实类型”(意味着整数类型或浮点类型,但实际上它始终是整数类型)。
With time_t, your best bet is to format it with strftime()after analyzing it with localtime()or gmtime()— this can be done portably.
使用time_t,您最好的选择是strftime()在使用localtime()或对其进行分析后对其进行格式化gmtime()- 这可以便携地完成。
Unportably, you have to determine by some mechanism what is the correct format specifier. You might use PRI_[Xxodi]_timeand SCN_[Xxodi]_timeor something similar as a non-standard but close-to-standard (without trampling on the reserved namespace — which is names starting PRI or SCN followed by a lower-case letter or X). You use some mechanism to specify that...encapsulating the unportable information in one place.
不可移植的是,您必须通过某种机制确定什么是正确的格式说明符。您可以使用PRI_[Xxodi]_time和SCN_[Xxodi]_time或类似的非标准但接近标准的东西(不会践踏保留的命名空间——名称以 PRI 或 SCN 开头,后跟小写字母或 X)。您使用某种机制来指定...将不可移植的信息封装在一个地方。

