我们可以创建一个类似scanf的函数,在填充所有参数时返回true,否则返回false而不循环遍历所有变量?

时间:2015-07-29 14:44:21

标签: c++ c variadic-templates variadic-functions variadic

我想用C ++(或C语言,如果需要)这样做。我研究了Variadic函数,我能想出的唯一方法在性能方面似乎相当差:

scanner(const char * string, const char * format, ...) // ... is the variables
{
  bool got_them_all(false);
  size_t length_of_list(0);
  va_list variables_list;
  va_start(variables_list, format);
  // Loop through variables_list and count until we run out of items
  ...
  if (length_of_list == sscanf(string, format, va_list))
  {
    got_them_all = true;
  }
  va_end(variables_list);
  return got_them_all;
}

在我的具体用例中,这些是命令参数,我知道字符串格式。我想要做的是避免错误,我计算5个参数但通过scanf(确实在我的情况下确实是sscanf)4或5.我会调用函数:   allOK = scanner(command_cstring, "CMD:%02d,%02d", inta, intb); 现在,在这种情况下,我可以很容易地看到有2个参数,所以我可以可靠地执行if (2 = scanner(command_cstring, "CMD:%02d,%02d", inta, intb));。当它超过六个参数时,我认为我没有出错的可能性相当高。

我宁愿不为我的动态传入字符串处理添加一个循环来计算参数。这听起来像是浪费了这个小型嵌入式系统的CPU时间。

似乎没有标准的方法来做sizeof(va_list)。

Variadic模板听起来很有希望。我不介意编译时计算负载,因为此时代码具有我要输入的最长变量列表。我没有可用的C ++ 11编译器,但我很乐意接受一个需要未来的解决方案。如果我今天有一个C ++ 11选项,那么我现在可能会尝试将自己的东西放在一起。

2 个答案:

答案 0 :(得分:2)

无法在运行时告诉有多少参数传递给varargs函数。你也不能说出论证的类型是什么。简而言之,你有责任做到正确。

但是,如果您使用的是gcc或clang且格式字符串是文字字符串,那么编译器会在格式字符串与参数的数量或类型不匹配时发出警告。此警告已通过-Wformat启用,但它也是-Wall启用的许多有用警告之一。 (如果你在没有-Wall的情况下进行编译,你实际上是戴着眼罩。)

答案 1 :(得分:1)

template<class...Ts>
bool scanner(const char * string, const char * format, Ts const&...ts)
{
  size_t num_scanned = sscanf(string, format, ts...);
  bool got_them_all = num_scanned == sizeof...(ts);
  return got_them_all;
}

会这样做。但请注意,如果您在字符串中指定的参数多于传递的参数,则您将在sscanf中执行未定义的行为。

很烦人,您希望在调用format之前自己扫描sscanf以获取格式说明符,以确保其安全。至少在调试版本中执行此操作。