【问题标题】:Odd behavior of function with variable number of parameters in CC中具有可变参数数量的函数的奇怪行为
【发布时间】:2013-02-09 14:49:26
【问题描述】:

我有以下带有可变数量参数的 C 函数,它应该通过哈希表搜索 char* word 并在文件中写入 truefalse,如果指定,它是第二个参数;否则为stdout

如果我指定文件名,它工作正常,问题是当我不指定时(例如find("foo"))。在这种情况下,它将结果写入名为 foo 而不是 stdout 的文件中。

是什么原因?

void find(char* word, ...)
{
va_list list;
char *fname = NULL;
va_start(list, word);
FILE* f;
fname = strdup(va_arg(list, char*));
va_end(list);
if (<condition>)    // condition suited for the case in which the file name is received 
    f = fopen(fname, "a");
else
    f = stdout;
if (member(word))
    fprintf(f, "True\n");
else
    fprintf(f, "False\n");
}

代替&lt;condition&gt;,我尝试了fname != NULLstrlen(fname) &gt; 0,但这些都不适用,并且当未指定fname 时,它一直将fname 视为word

非常感谢您提供的任何帮助。

【问题讨论】:

  • 不应该以这种方式使用可变参数。您最好使用void find(char* word, char* filename) 并检查filename 是否为NULL,如果是则写入标准输出。如果您确实打开了文件,也不要忘记关闭您打开的文件。

标签: c list arguments stdout variable-length


【解决方案1】:

来自va_* 的手册页:

如果没有下一个参数,或者如果 type 与 实际下一个参数的类型(根据默认值提升) 参数提升),会出现随机错误

如果你想使用可变参数列表,你需要为列表设计某种终结符(例如,总是添加一个虚拟的 NULL 参数):

find (word, NULL);
find (word, filename, NULL);

或提供参数的数量作为参数:

find (1, word);
find (2, word, filename);

【讨论】:

  • 好的,谢谢你记得我。它与列表末尾的 NULL 一起使用。最初我认为 NULL(或其他行为)以某种方式隐含在未收到的参数中,但它本身并不知道列表何时结束。
猜你喜欢
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2023-03-18
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多