V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
diffworld
V2EX  ›  问与答

关于 ncurses 滚屏的问题

  •  
  •   diffworld · 2017-03-13 16:58:05 +08:00 · 1518 次点击
    这是一个创建于 2601 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1. 想要实现的功能

    在屏幕的最下面一行输入字符串,然后在上方新建一个窗口将字符串显示出来,显示的字符串很多,所以可能需要给窗口设置滚屏,可是试了好多种办法都不能实现,请问有人知道怎么做吗?

    2. 我的代码

    #include <ncurses.h>
    
    int main(int argc, char *argv[])
    {
        
        initscr();
        int lines, cols;
        getmaxyx(stdscr, lines, cols);
    
        WINDOW *my_win = newwin(lines-3,cols,0,0);
        scroll(my_win);
        //下面的两行是针对滚屏的设置,但是没有效果
        scrollok(my_win, TRUE); 
        wsetscrreg(my_win, 0, lines);
        box(my_win, ACS_VLINE, ACS_HLINE);
        refresh();
        wrefresh(my_win);
        
    
        char str[256];
        int x = 0;
        while(1)
        {
            mvwprintw(stdscr, LINES-1, 0, "Enter string: ");
            getstr(str);
            mvwprintw(my_win, x, 0, "You Entered: %s", str); //从屏幕最上方往下依次显示字符串
            refresh();
            wrefresh(my_win);
            x++;
        }
    
        getch();
        endwin();
        return 0;
    }
    
    
    1 条回复    2017-03-14 09:59:34 +08:00
    diffworld
        1
    diffworld  
    OP
       2017-03-14 09:59:34 +08:00
    自问自答:

    1. 首先`scrollok`和`wsetscrreg`是有有效的,`scrollok`开启屏幕滚动,`wsetscrreg`设置滚动的范,`mvwprintw` 是移动到某个位置进行输出
    2. 问题中代码不能生效的原因是 `x++`这句,这句的本意是从上到下,每输出一行行号加 1,配合`mvwprintw`也就是定位到下一行进行输出,但是如果当前屏幕的最大行数只有 80 行,而随着输出增多, x 必然会大于 80,假设 x=100,此时`mvwprintw`会定位到第 100 行的位置进行输出,而 100 行并不在屏幕内,所以不会在屏幕上显示输出

    解决方法是,当 x 到达最大行数的时候,换用另外一种输出形式,比如`printw`、`wprintw`等等

    所以修改之后的代码可以是这样的

    ```c
    #include <ncurses.h>

    int main(int argc, char *argv[])
    {

    initscr();
    int lines, cols, win_lines, win_cols;
    getmaxyx(stdscr, lines, cols);

    WINDOW *my_win = newwin(lines-3,cols,0,0);
    getmaxyx(my_win, win_lines, win_cols);

    scrollok(my_win, TRUE);
    wsetscrreg(my_win, 0, lines);
    refresh();
    wrefresh(my_win);


    char str[256];
    int x = 0;
    while(1)
    {

    mvwprintw(stdscr, LINES-1, 0, "Enter string: ");
    getstr(str);
    mvwprintw(my_win, x, 0, "You Entered: %s", str);
    refresh();
    wrefresh(my_win);
    x++;

    if (x > win_lines)
    {
    wprintw(my_win, "\nYou Entered: %s", str);
    refresh();
    wrefresh(my_win);
    }
    }

    endwin();
    return 0;
    }

    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2853 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:46 · PVG 22:46 · LAX 07:46 · JFK 10:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.