【问题标题】:How to wrap ncurses's printw function?如何包装 ncurses 的 printw 函数?
【发布时间】:2014-05-17 18:46:38
【问题描述】:

我正在学习如何使用 ncurses,并想使用 RAII 来自动初始化和结束窗口:

class CWindow
{
public:
   CWindow() {initscr();}
   ~CWindow() {endwin();}
};

这是 CWindow 类的基本思想。它现在仅适用于 stdscr,因此使用 addch()、printw() 等函数不是问题。但是,这个类最终会被用来表示 ncurses windows(WINDOW*)。添加像 print 这样的成员函数会很直观,这样就可以代替使用

wprintw(win.getWin(), "str %i", someVar);

可以写

win.print("str %i", someVar);

我在网上看了,但在我看来,只有 cstdio 的 prinf 和类似的功能被包装了。并且 cstdio 提供了一种简单的方法,具有接受 va_list 的函数。但是,ncurses 没有这组函数。

说实话,我更喜欢使用 C++ 而不是 C,所以我的 C 知识并不出色。我也没有创建任何变量参数列表函数。我尝试了幼稚的方法:

void print(const char* str, ...)
{
    va_list args;
    va_start(args, str);
    printw(str, args);
    va_end(args);
}

但是,它不起作用。我还尝试在this 线程中合并可变参数宏,但它对我不起作用。不过我可能做错了。

无论如何,我怎样才能做到这一点?

【问题讨论】:

  • 寻找“可变参数模板”,或者更好的是,让你的 CWindow 类成为一种 iostream 类并使用插入器和提取器(operator <<operator >>)...
  • 我也见过可变参数模板,但他们说可变参数模板将为每组参数创建单独的函数(因为这是模板的工作方式)。因此,它对代码大小无效。我也想过operator>,但我想保持界面一致,我想使用函数mvprintw(const char* str, ...),将光标移动到(y, x),然后在那里打印 str。
  • 经过充分优化,您的可变参数模板调用应该内联到原始的mvprintwprintw 调用,问题没有实际意义。无论如何,请参阅下面的答案...

标签: c++ ncurses


【解决方案1】:

@massa 的回答可以改进:

  • 虽然 ncurses 接受 vwprintw,但首选形式是 vw_printw
  • 不必使用initscr的返回值; stdscr 变量具有相同的值。

通过这些修复:

void print(const char* str, ...)
{
    va_list args;
    va_start(args, str);
    vw_printw(stdscr, str, args);
    va_end(args);
}

进一步阅读:

【讨论】:

  • vw_printw 返回一个带有 OK 或 ERR 的 int,这可能有利于此打印函数将其包装以返回。
【解决方案2】:

你几乎是在做你想做的事的正确道路,只是改变

printw(string, args);

WINDOW *win = initscr();
// ...
vwprintw(win, string, args);

【讨论】:

  • 编辑:好的;它实际上是 vwprintw; printw 没有它的 v 功能...感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2020-08-31
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多