将可变参数列表转发到 c 中的 ncurses printw 函数

Forward Variadic Argument List to ncurses printw function in c

有人以多种不同的方式询问过这个问题。但是我仍然无法让它工作。这是我的函数定义。

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("Hello %d", var) 这样调用 ncurses_add_line,我会得到一个不存储在 var 中的值。但是,如果我调用 printw("Hello %d", var),我会看到 var 的值显示在 "Hello" 旁边,如 if var == 1 then "Hello 1" 打印为 printw 但这是ncurses_add_line.

不是这种情况

我需要更改什么?

我之所以总结这个是因为我不想包含在我的头文件中,只包含在我的 c 文件中。

尝试 vwprintw 而不是 printwvwprintw 以 va_list 作为参数。

您尝试使用的惯用语——将 va_list 传递给一个参数数量可变的函数——是行不通的。一种解决方案是找到一个可用的函数变体(在本例中为 vwprintw)。另一种方法是 "flatten" va_list:在这种情况下,您可以使用 vsprintf 创建格式化字符串,然后将其传递给 curses。

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);                                                              
  }                                                                            
}