如何在不清除屏幕的情况下使用来自curses的getch?

时间:2011-01-23 03:01:59

标签: c ncurses curses

我正在学习用C语言编程,并希望能够在我的代码运行时在终端中键入字符而不按 return 。我的程序有效,但是当我呼叫initscr()时,屏幕被清除 - 即使在呼叫filter()之后。 filter的文档表明它应该禁用清除 - 但对我来说情况并非如此。

#include <stdio.h>
#include <curses.h>
#include <term.h>

int main(void) {

    int ch;

    filter();
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    while((ch = getch()) != EOF);

    endwin();

    return 0;
}

为什么上面的代码仍然清除屏幕,以及可以采取哪些措施来修复它?

如果有帮助,我正在使用Debian Lenny(稳定版)和gnome-terminal。

4 个答案:

答案 0 :(得分:4)

通过mike.dld扩展答案,这适用于MacOS X 10.6.6(GCC 4.5.2)和系统curses库 - 无需清除屏幕。我添加了记录键入的字符(记录到文件“x”)的功能,以及键入 CONTROL-D 并停止程序而不是强制用户中断的功能。

#include <stdio.h>
#include <curses.h>
#include <term.h>

#define CONTROL(x)  ((x) & 0x1F)

int main(void)
{
    FILE *fp = fopen("x", "w");
    if (fp == 0)
        return(-1);
    SCREEN *s = newterm(NULL, stdin, stdout);
    if (s == 0)
        return(-1);
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    int ch;
    while ((ch = getch()) != EOF && ch != CONTROL('d'))
        fprintf(fp, "%d\n", ch);

    endwin();

    return 0;
}

答案 1 :(得分:3)

使用newterm()代替initscr(),您应该没问题。如果你遵循这个建议,不要忘记delscreen()

答案 2 :(得分:2)

由于以下原因之一,您会在curses应用程序中看到您的屏幕被清除:

  • 您的程序调用{​​{3}}(清除屏幕)或initscr,而无需先致电newterm,或
  • 终端初始化清除屏幕(或通过切换到备用屏幕使其显示为清除)。

在后一种情况下,您可以通过将enter_ca_modeexit_ca_mode指针重置为NULL filter来抑制ncurses中的备用屏幕功能。更好的是,选择一个符合你想要的终端描述。

进一步阅读:

答案 3 :(得分:1)

基本上,curses旨在接管屏幕(或窗口,在窗口终端的情况下)。你不能真正将curses与stdio混合在一起,你不能真正使用curses来输入或输出一些内容而不会弄乱屏幕的其余部分。有一些部分的解决方法,但你真的无法让它按照你想要的方式工作。遗憾。

我建议重写你的程序以使用curses,或者调查readline之类的替代方案。