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

发布于 2024-10-13 19:29:16 字数 578 浏览 4 评论 0原文

我正在学习用 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(如果有帮助的话)。

I'm learning to program in C and want to be able to type characters into the terminal while my code is running without pressing return. My program works, however when I call initscr(), the screen is cleared - even after calling filter(). The documentation for filter suggests it should disable clearing - however this is not the case for me.

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

Why does the above code still clearr the screen, and what could be done to fix it?

I'm using Debian Lenny (stable) and gnome-terminal if that helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小忆控 2024-10-20 19:29:16

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

  • 您的程序调用 initscr(清除屏幕)或newterm 无需先调用 filter,或者
  • 终端初始化清除屏幕(或者通过切换到备用屏幕使其看起来是清除的)。

在后一种情况下,您可以通过将 enter_ca_modeexit_ca_mode 指针重置为 NULL dialog 中所做的那样。更好的是,选择一个符合您要求的终端描述。

进一步阅读:

You would see your screen cleared in a curses application for one of these reasons:

  • your program calls initscr (which clears the screen) or newterm without first calling filter, or
  • the terminal initialization clears the screen (or makes it appear to clear, by switching to the alternate screen).

In the latter case, you can suppress the alternate screen feature in ncurses by resetting the enter_ca_mode and exit_ca_mode pointers to NULL as done in dialog. Better yet, choose a terminal description which does what you want.

Further reading:

梦初启 2024-10-20 19:29:16

通过 mike.dld 扩展答案,这对我来说适用于 MacOS X 10.6.6 (GCC 4.5.2) 和系统诅咒库 - 无需清除屏幕。我添加了记录输入字符的功能(记录到文件“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;
}

Extending the answer by mike.dld, this works for me on MacOS X 10.6.6 (GCC 4.5.2) with the system curses library - without clearing the screen. I added the ability to record the characters typed (logged to a file "x"), and the ability to type CONTROL-D and stop the program rather than forcing the user to interrupt.

#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;
}
怎言笑 2024-10-20 19:29:16

使用 newterm() 而不是 initscr(),那么你应该没问题。如果您遵循此建议,请不要忘记 delscreen()

Use newterm() instead of initscr(), you should be fine then. And don't forget about delscreen() if you follow this advice.

2024-10-20 19:29:16

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

我建议要么重写你的程序以在整个程序中使用curses,要么研究像readline这样的替代方案。

Basically, curses is designed to take over the screen (or window, in the case of a windowed terminal). You can't really mix curses with stdio, and you can't really use curses to just input or output something without messing with the rest of the screen. There are partial workarounds, but you're never really going to be able to make it work the way that it sounds like you want to. Sorry.

I'd suggest either rewriting your program to use curses throughout, or investigating alternatives like readline.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文