如何设置控制台光标位置以输出到标准输出(stdout)?

3

我想设置光标位置以在控制台屏幕上打印一个字符。是否有不使用ncurses库的解决方案。

下面的example中是否有Linux中SetConsoleCursorPosition的等效调用:

void print (int x, int y, char c) {
    COORD p = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
    printf("%c", c);
}
1个回答

7
也许需要一点历史背景。在Windows中,你所谓的“控制台”实际上是终端仿真器的一个例子;然而,与传统的终端仿真器不同的是,Windows通过其控制台API直接访问终端。终端(因此终端仿真器)采取的传统方法是解释转义序列,每个序列指示终端执行某些操作。
不幸的是,正如你所想象的那样,终端的功能差异很大(有些甚至可以绘制各种图形),因此并非所有终端都使用相同的转义序列集。现在,你很难遇到没有实现超集 ANSI/VT100 escapes的终端;如果你只支持ANSI/VT100及其衍生版本,你可以发送ESC [ n; m H,其中n是行号,m是列号。
然而,如果你这样做,当代码面对任何奇特的东西时就无法工作。在这种情况下,你真的应该考虑使用一个curses库(ncurses是一个常见但不是唯一的例子),即使你只是用它来从terminfo数据库中提取信息(尽管我强烈建议只使用curses库)。
最后,需要注意的是:你引用的Windows代码不一定会起作用!为什么?因为printf()输出是有缓存的,并不能保证在改变光标位置之前字符已经被发送到控制台。你可以通过使用fflush(stdout)来解决这个问题,但是如果你正在使用SetConsoleCursorPosition,那么你可能会直接使用WriteConsole并完成它。
附加有用信息:
你实际上可以获得一个在Windows上运行的curses版本;参见例如PDCurses。如果你使用curses,那么你就不需要任何特定于Windows的代码,而且你可以在任何终端上使用。

我们可以使用termios.h中的struct termios及其API,而不是使用ESC序列。我想了解获取当前光标位置的低级Linux调用。 - manav m-n
@Manav,Linux没有任何低级别的调用可以获取当前光标位置。你需要使用转义序列。为什么?因为只有终端(可能是单独的硬件)知道光标的位置。您需要发送一个转义序列来询问它,它将回复答案。要获取光标位置,请发送“ESC [6n”,然后读取回复(其中将包含光标位置的“ESC [n; m R”序列)。但是,说真的,请使用CURSES!它更容易,更好。 - al45tair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接