sscanf包装函数在C中前进字符串指针

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().有没有办法解决这个问题,或者我是否也可以在每次通话时手动处理簿记?

caf*_*caf 4

你是对的 - 你不能将额外的参数填充到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)