繁体   English   中英

具有可变数量参数的打印函数

[英]Printing function with variable number of arguments

我有这个功能:

void print(THashEntry *entry, ...)
{
    va_list parameters;

    va_start(parameters, entry);

    while (true)
    {
        THashEntry *currentEntry = va_arg(parameters, THashEntry *);
        if (!currentEntry)
        {
            break;
        }

        printf("%s\n", currentEntry->value);
    }



 va_end(parameters);
}

我将这些条目的地址传递给函数,然后我想访问它们的成员“值”并打印它。

但是,当我尝试通过 va_arg 获取参数时,它返回的不是第一个参数,而是从一开始就返回第二个参数,并且当进入另一个循环循环时,这是分段错误。

正如 John Kugelman 在他的回答中所说,以下是将可变数量的参数传递给 printf/sprintf 的一些好的做法:-

 void Error(const char* format, ...)
 {
  va_list argptr;
  va_start(argptr, format);
  vfprintf(stderr, format, argptr);
  va_end(argptr);
 }

当您到达参数列表的末尾时, va_arg不会返回NULL 正如man va_arg所说:

会发生随机错误

因此,要绕过它,您要么需要将参数数量传递给print函数,要么结束终止符。

要在编译时自动计算参数数量,您可以使用宏

#define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__})/sizeof(int))

此答案中查看更多详细信息

我很抱歉插入您的设计,但这可能是使用的替代方法

 struct abc {
    int a;
    char b[10];
 };

 void f(int size, abc* a) {
    for (int i = 0; i < size; i++) {
    abc x = a[i];
    }
 }

int _tmain(int argc, _TCHAR* argv[])
{
abc *arrAbc = new abc[10];
for (int i = 0; i < 10; i++) {
    arrAbc[i].a = 0;
}
f(10, arrAbc);
}

似乎有很多答案,但就我个人而言,我从来没有找到一种很好的方法来绕过动态计算 va_list 中 args 的数量。

也就是说,有几种方法可以解决它:

  • 使用 NUMARGS(...) 宏,如 qrdl 所述
  • 将参数的数量传递给函数,就像 main 一样void print(int numArgs, MyEntry *entry, ...)
  • 使用 NULL 终止列表

后者恰好是我个人的偏好,因为它往往符合我(并且看起来也像你的)如何抓住列表末尾的本能。 见下文:

 #import <stdarg.h>

 typedef struct MyEntry {
     int a;
     int b;
 } MyEntry;

 void print(int numArgs, MyEntry *entry, ...) {

     va_list parameters;

     va_start(parameters, entry);

     MyEntry *m;
     for ( m = entry; m != NULL; m = va_arg(parameters, MyEntry *))  {        
         printf("%d\n", (int)m->a);
     }

     va_end(parameters);
 }

 int main(int argc, char *argv[]) {

     MyEntry entry = { 10, 20 };
     MyEntry entry2 = { 30, 40 };
     MyEntry entry3 = { 50, 60 };
     MyEntry entry4 = { 70, 80 };
     MyEntry entry5 = { 90, 100 };

     print(2, &entry, &entry2, &entry3, &entry4, &entry5, NULL);
     return 1;
 }

快乐编码!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM