转发Variadic Argument List来修复c中的printw函数

时间:2016-11-19 05:15:39

标签: c variadic-macros

这有几种不同的口味。然而,我仍然无法让它发挥作用。这是我的功能定义。

void                                                                           
ncurses_add_line(const char *fmt, ...)                                         
{                                                                              
  if (ncurses_window) {                                                        
    va_list args;                                                              
    va_start(args, fmt);                                                       
    printw(fmt, args);                                                           
    printw("\n");                                         
    va_end(args);                                                              
  }                                                                            
}

当我调用这个函数时,我在函数的可变参数中得到了胡言乱语。如果我直接致电printw,一切正常。例如,如果我像ncurses_add_line那样调用ncurses_add_line("Hello %d", var),我会得到一个不存储在var中的值。但是,如果我调用printw("Hello %d", var),我会看到var的值显示在“Hello”旁边,如果var == 1那么“Hello 1”会打印printw,但事实并非如此ncurses_add_line

我需要改变什么?

我把它包装起来的原因是因为我不想在我的头文件中包含,只在我的c文件中。

2 个答案:

答案 0 :(得分:2)

尝试使用vwprintw代替printwvwprintw以va_list为参数。

您尝试使用的习惯用法 - 将va_list传递给带有可变数量参数的函数 - 不会起作用。一种解决方案是找到将起作用的函数的变体(在本例中为vwprintw)。另一种选择是“平坦化”#34; va_list:在这种情况下,你可以使用vsprintf创建一个格式化的字符串,然后将其传递给curses。

答案 1 :(得分:1)

args 类似于参数数组。这是一个内部结构。您必须通过传递类型来读出每个参数。请记住,在C中没有运行时反射,因此您必须在代码中添加类型。

void ncurses_add_line(const char *fmt, ...)                                         
{                                                                              
if (ncurses_window) 
{            
  va_list args; 
  va_start(args, fmt);       
  char *arg = va_arg( args, int ); // take out one arg by giving the type (int)
  printw(fmt, arg);   
  printw("\n");                                         
  va_end(args);                                                              
  }                                                                            
}