我想用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 */));
如何使用可变参数函数实现所需的扩展功能?
答案 0 :(得分:0)
我已经看到C预处理器代码循环使用可变参数宏的参数,我不希望它在我的代码中。但是,在您的情况下,您可以采取以下解决方案。我提出的宏最多可以处理4个参数,你肯定可以将它扩展到任何常量。
#define typecast4(type, a1, a2, a3, a4, ...) ((type)a1), ((type)a2), ((type)a3), ((type)a4)
#define typecast(type, ...) typecast4(type, __VA_ARGS__, NULL, NULL, NULL, NULL)
此特定解决方案始终生成4个参数。请注意,在您的情况下,这无关紧要,因为scanf接受并安全地忽略输入格式之外的任何参数。因此,以下代码编译:
int main() {
time_t x,y;
scanf("%lld, %lld", typecast(long long *, &x, &y));
...
}
但是,我担心从time_t *
到long long *
的演员阵容。它无处写,time_t
必须由long long
表示。如果它在某个平台上由int
表示,则之前的代码将是错误的。扫描您的值的正确方法如下:
int main() {
time_t x,y;
long long lx, ly;
scanf("%lld, %lld", &lx, &ly);
x = lx;
y = ly;
...
}
更正确,不需要任何可变参数宏。
答案 1 :(得分:-1)
使用boost
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#define CAMMA(r, data, i, elem) BOOST_PP_COMMA_IF(i)elem
#define CAST(r, data, elem) (data)elem
#define typecast(type, ...) BOOST_PP_SEQ_FOR_EACH_I(CAMMA, , BOOST_PP_SEQ_TRANSFORM(CAST, type, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))