Dus*_*sty 7 c scanf variadic-functions
我有一个函数,它进行一系列调用sscanf(),然后,在每个函数之后,更新字符串指针以指向未被消耗的第一个字符,sscanf()如下所示:
if(sscanf(str, "%d%n", &fooInt, &length) != 1)
{
// error handling
}
str+=length;
Run Code Online (Sandbox Code Playgroud)
为了清理它并避免重复这几次,我想把它封装成一个很好的实用函数,看起来如下所示:
int newSscanf ( char ** str, const char * format, ...)
{
int rv;
int length;
char buf[MAX_LENGTH];
va_list args;
strcpy(buf, format);
strcat(buf, "%n");
va_start(args, format);
rv = vsscanf(*str, buf, args, &length); //Not valid but this is the spirit
va_end(args);
*str += length;
return rv;
}
Run Code Online (Sandbox Code Playgroud)
然后我可以简化下面的调用来删除附加参数/簿记:
if(newSscanf(&str, "%d", &fooInt) != 1)
{
// error handling
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我找不到一种方法将&length参数直接附加到arg列表的末尾或其他内部newSscanf().有没有办法解决这个问题,或者我是否也可以在每次通话时手动处理簿记?
你是对的 - 你不能将额外的参数填充到va_list. 你能做的最好的可能就是一些像这样的宏技巧:
int _newSscanf ( char ** str, int *length, const char * format, ...)
{
int rv;
va_list args;
va_start(args, format);
rv = vsscanf(*str, format, args);
va_end(args);
*str += *length;
return rv;
}
#define NEW_SSCANF_INIT int _ss_len
#define newSscanf(str, fmt, ...) _newSscanf(str, &_ss_len, fmt "%n", __VA_ARGS__, &_ss_len)
Run Code Online (Sandbox Code Playgroud)
...并要求调用者执行以下操作:
NEW_SSCANF_INIT;
if (newSscanf(&str, "%d", &fooInt) != 1)
{
// error handling
}
Run Code Online (Sandbox Code Playgroud)
如果您可以使用 GCC 扩展,则可以使用“语句表达式”来删除该NEW_SSCANF_INIT部分,使其更清晰:
#define newSscanf(str, fmt, ...) ({int _ss_len; _newSscanf(str, &_ss_len, fmt "%n", __VA_ARGS__, &_ss_len);})
Run Code Online (Sandbox Code Playgroud)