【发布时间】:2014-11-20 13:24:15
【问题描述】:
我想用sscanf来解析一个长字符串..
要解析的数据将存储在一个结构中,其成员的类型都是time_t。
不幸的是,没有任何格式字符串来标记time_t,所以我只想将所有time_t * 参数类型转换为unsigned long long *,因为它是一个非常长的字符串,有很多参数,每个参数一个一个只会弄乱我的编辑器屏幕..
所以,我创建了一个宏来简化这个:
#define typecast(type, ...) (type) __VA_ARGS__
我这样调用它:
sscanf(string, PARSE_STRING,
typecast(unsigned long long *, /* my arguments */));
虽然这会扩展为:
sscanf(string, PARSE_STRING,
(unsigned long long *) /* arg1 */, (unsigned long long *) /* arg2 */, /* and so on */);
但是在用gcc -E检查之后,我发现它扩展到了这个:
sscanf(string, PARSE_STRING,
(unsigned long long *) /* arg1 */, /* arg2 */, /* and so on */));
如何使用可变参数函数实现我想要的扩展功能?
【问题讨论】:
-
你可能会得到一些灵感here。
-
This question也有一些相关的答案。
-
请注意,
time_t通常是有符号整数类型。如果您正在扫描,则必须确保该类型与time_t兼容——它在某种程度上是特定于平台的。 -
@JonathanLeffler:我不知道
time_t已签名,因为时间要么为零,要么为正,但无论如何,我确信我正在读取的数据永远不会有负值。 -
传统上,时间 0 是 1970-01-01 00:00:00 Z(或 +00:00)。
mktime()函数在出错时返回(time_t)-1。对于 32 位有符号类型(旧 32 位系统上的long),可表示时间的范围大致是从 1901-12-13 (0x80000000) 到 2038-01-18 (0x7FFFFFFF)。这就是为什么您有时会看到有关 Y2038 危机的 cmets; 32 位签名的time_t将翻转。大多数系统现在使用 64 位time_t来避免该问题(以及 Y10K 问题等)。
标签: c arguments c-preprocessor variadic-macros