ncurses mvaddch()光标移动可能的bug?

时间:2015-03-30 09:34:38

标签: c ncurses cursor-position

代码:

#include <ncurses.h>

int main(int argc, char **argv)
{
    initscr();
    noecho();
    cbreak();


    mvprintw(0, 0, curses_version());
    mvprintw(1, 0, "Hello World");
    mvaddch(2, 0, mvinch(1, 4));                 // Why doesn't this work?

    getch();
    endwin();

    return 0;
}

输出:

ncurses 5.9.20130608  
Hello World  

指针在getch o之后闪烁(等待Hello)。

问题:
与在C中一样,在调用该函数之前首先计算传递给函数的参数,然后首先调用mvinch(),当它返回字符o时,将调用mvaddch()的调用。
但是为什么字符o没有打印在第2行(正好在Hello World下面)?而是mvaddch在当前光标位置打印o(感谢winch,即1,4)。此处mvaddch()的行为与addch的行为完全不同,mv前缀和给定的明确移动坐标。为什么?

这是mvaddch()中可能存在的错误还是我错过了什么?

编辑:
$ uname -a
Linux Titanic 3.11.0-26-generic #45-Ubuntu SMP Tue Jul 15 04:02:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

2 个答案:

答案 0 :(得分:3)

问题在于mvaddch()碰巧实现为宏。像

这样的电话
mvaddch(2, 0, foo);

扩展为以下内容(删除了一些括号):

wmove(stdscr, 2, 0) == -1 ? -1 : waddch(stdscr, foo);

您可以使用例如gcc -E

如上所示,foo将在wmove()之后进行评估,这意味着foo设置的任何光标位置都将优先。

要解决此问题,您可以将mvinch()的结果明确保存到chtype变量,并在调用mvaddch()时使用该变量。

mvinch()似乎也是一个宏,以wmove()winch()来实现。)

答案 1 :(得分:1)

问题是mvaddchmvinch移动了相同的光标位置,并且mvinch稍后会被评估。

结果是&#34; o&#34;被添加回读取它的单元格中,没有明显的变化。

mvaddchmvinch通常都是宏。您可以通过#undef来改变它,或者将宏名称放在括号中,例如,

(mvaddch)(2, 0, (mvinch)(1, 4));

因为 move 是在函数之外计算的,所以评估的顺序由宏决定。