1

我正在尝试使用 c++ 中的 ANSI 转义码滚动屏幕,但我遇到了问题。我的代码是

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <iostream>
#include <cstdlib>

int main() {
    system("clear");
    std::cout << "Press ESC to quit" << std::endl;

    struct termios oldSettings, newSettings;

    tcgetattr(fileno(stdin), &oldSettings);
    newSettings = oldSettings;

    newSettings.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr(fileno(stdin), TCSANOW, &newSettings);

    while (1) {
        char c;
        read(fileno(stdin), &c, 1);

        if (c == 27) { // ESC or arrow?
            fd_set set;
            struct timeval tv;

            tv.tv_sec = 0;
            tv.tv_usec = 0;

            FD_ZERO(&set);
            FD_SET(fileno(stdin), &set);

            int res = select(fileno(stdin) + 1, &set, NULL, NULL, &tv);

            if (res > 0) {
                read(fileno(stdin), &c, 1);

                if (c == 91) {
                    read(fileno(stdin), &c, 1);

                    switch (c) {
                        case 65:
                            std::cout << "\033[1A" << std::flush; // arrow up
                            break;

                        case 66:
                            std::cout << "\033[1B" << std::flush; // arrow down
                            break;

                        case 67:
                            std::cout << "\033M" << std::flush; // arrow right
                            break;

                        case 68:
                            std::cout << "\033D" << std::flush; // arrow left
                            break;

                        default:
                            while (res != 0) {
                                read(fileno(stdin), &c, 1);

                                fd_set set;
                                struct timeval tv;

                                tv.tv_sec = 0;
                                tv.tv_usec = 0;

                                FD_ZERO(&set);
                                FD_SET(fileno(stdin), &set);
                                res = select(fileno(stdin) + 1, &set, NULL,
                                             NULL, &tv);
                            }
                            break;
                    }
                }
            }

            else
                break; // ESC
        }
    }

    tcsetattr(fileno(stdin), TCSANOW, &oldSettings);

    system("clear");
    return 0;
}

当我运行程序时,如果我按向下箭头直到光标移动到最后一行,然后按向左箭头,屏幕向下滚动(这很好)。但是,如果我用向上箭头向上移动光标,然后按向右箭头,则不会再次出现“按 ESC 退出”字样。我该怎么做才能将屏幕向上滚动到上一行?

4

0 回答 0