在ncurses中实现文本滚动的推荐方法是什么?

在ncurses中实现文本滚动的推荐方法是什么?,c,ncurses,curses,C,Ncurses,Curses,我正在尝试实现一个ncurses应用程序,文本滚动更少。推荐的方法是什么 以下是我所知道的: 您可以使用滚动将文本缓冲区上下移动1行。但是,如果向下滚动,则会在顶部出现一个空行,如果向上滚动,则会在底部出现一个空行,您必须自己重新绘制 Ncurses为您做文字包装,当我必须确定在步骤1中要重新绘制哪一行时,这会把我的数学搞砸 我想我可以自己重新实现wordwrap并保留一个包含所有后包装行的数组,但这似乎是一个常见问题,因此可能有更好的方法。ncurses只知道当前屏幕。滚动屏幕时,ncurse

我正在尝试实现一个ncurses应用程序,文本滚动更少。推荐的方法是什么

以下是我所知道的:

  • 您可以使用
    滚动
    将文本缓冲区上下移动1行。但是,如果向下滚动,则会在顶部出现一个空行,如果向上滚动,则会在底部出现一个空行,您必须自己重新绘制
  • Ncurses为您做文字包装,当我必须确定在步骤1中要重新绘制哪一行时,这会把我的数学搞砸

  • 我想我可以自己重新实现wordwrap并保留一个包含所有后包装行的数组,但这似乎是一个常见问题,因此可能有更好的方法。

    ncurses只知道当前屏幕。滚动屏幕时,ncurses不会跟踪离开屏幕的任何文本。您的终端可能有一个回滚缓冲区,但该缓冲区独立于ncurses,curses无法查看终端的回滚缓冲区

    如果需要滚动,我希望您需要跟踪文件中的当前位置


    我不认为ncurses有自动换行功能。你怎么做自动换行功能?

    我对ncurses还不是很有经验,所以我不知道所有的库函数,但是保持一个文本行的双链接列表可以工作。这是一个原始的less克隆:

    #include <ncurses.h>
    #include <stdlib.h>
    
    #define MAXLEN 128
    
    typedef struct Line {
        char contents[MAXLEN];
        struct Line *prev, *next;
    } Line;
    
    Line *head, *curr;
    
    int nr_lines;
    int curr_line;
    
    int term_rows, term_cols;
    
    void load(const char *filename);
    void draw(Line *l);
    
    int main(int argc, char **argv)
    {
        if (argc == 1)
        {
            fputs("less: No file to open\n", stderr);
            return 1;
        }
    
        initscr();
        noecho();
        keypad(stdscr, TRUE);   // for KEY_UP, KEY_DOWN
        getmaxyx(stdscr, term_rows, term_cols);
        addstr("Reading text...\n");
    
        load(argv[1]);
    
        curr = head;
        curr_line = 0;
        draw(curr);
    
        int ch;
        while ((ch = getch()) != EOF && ch != 'q')
        {
            if (ch == KEY_UP && curr->prev != NULL)
            {
                curr_line--;
                curr = curr->prev;
            }
            else if (ch == KEY_DOWN && curr->next != NULL
                && curr_line + term_rows < nr_lines)
            {
                curr_line++;
                curr = curr->next;
            }
            draw(curr);
        }
    
        endwin();
        return 0;
    }
    
    void load(const char *filename)
    {
        FILE *fp = fopen(filename, "r");
        Line *lp;
    
        head = malloc(sizeof(Line));
        head->prev = head->next = NULL;
        curr = head;
    
        while (fgets(curr->contents, MAXLEN, fp))
        {
            lp = malloc(sizeof(Line));
            lp->prev = curr;
            curr->next = lp;
            curr = lp;
            nr_lines++;
        }
        curr->next = NULL;
    }
    
    void draw(Line *l)
    {
        int i;
        clear();
        for (i = 0; i < term_rows && l != NULL; i++, l = l->next)
            addstr(l->contents);
    }
    
    #包括
    #包括
    #定义MAXLEN 128
    typedef结构行{
    字符内容[MAXLEN];
    结构行*上一行,*下一行;
    }线路;
    行*头,*当前;
    国际天然气管线;
    国际货币线;
    int term_行,term_列;
    无效加载(常量字符*文件名);
    虚线图(线*l);
    int main(int argc,字符**argv)
    {
    如果(argc==1)
    {
    fputs(“更少:没有要打开的文件”,stderr);
    返回1;
    }
    initscr();
    noecho();
    键盘(stdscr,TRUE);//向上键,向下键
    getmaxyx(stdscr、term_行、term_列);
    addstr(“读取文本…\n”);
    载荷(argv[1]);
    curr=头;
    电流线=0;
    提款(货币);
    int-ch;
    while((ch=getch())!=EOF&&ch!=“q”)
    {
    如果(ch==KEY\u UP&&curr->prev!=NULL)
    {
    货币线--;
    当前=当前->当前;
    }
    否则,如果(ch==向下键和当前键->下一步!=NULL
    &&当前行+术语行下一步;
    }
    提款(货币);
    }
    endwin();
    返回0;
    }
    无效加载(常量字符*文件名)
    {
    FILE*fp=fopen(文件名,“r”);
    行*lp;
    水头=malloc(线的尺寸);
    head->prev=head->next=NULL;
    curr=头;
    while(fgets(curr->contents,MAXLEN,fp))
    {
    lp=malloc(sizeof(Line));
    lp->prev=当前;
    curr->next=lp;
    curr=lp;
    nr_行++;
    }
    当前->下一步=空;
    }
    虚线绘制(线*l)
    {
    int i;
    清除();
    对于(i=0;inext)
    addstr(l->contents);
    }
    
    我不确定这将如何处理长度超过128个字符的行,但对于不同的解决方案,这是一个不同的问题


    至于换行,如果您不需要保留原始文本格式,可以在从文件中读取长行时将其拆分为两行。

    答案取决于您有多少文本,以及您在屏幕上对数据的其他用途。但通常,该功能是显示可滚动文本的首选方式。这不仅是ncurses的一个特性,而且大多数curses的实现都支持这一特性(即,20世纪80年代后期以后的任何东西)

    键盘类似于窗口,但其大小不限于当前屏幕大小。相反,数据通过一个视图显示,该视图在焊盘中的位置可以轻松更改

    ncurses examples
    中有两个相关的示例程序:通过将文件内容写入窗口来显示文件,同时使用画板绘制整个文件,并使用画板功能根据需要上下左右移动视图

    在这些程序中,
    show_all
    函数进行实际绘图,与
    view.c
    的等效值(94行)相比,其长度约为(35行)的三分之一


    进一步阅读:将的讨论作为比较网络课程和俚语库的示例。

    用您正在使用的语言标记此问题,以便可以看到该问题。ncurses标签可能没有那么流行。从中,似乎还有一个
    scrl()
    方法。这有什么不同的影响吗?西迪尔:刚刚有(node.js),但我不认为有很多人在里面写诅咒应用程序。