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を押して終了します」という書き込みが再び表示されません。画面を前の行までスクロールするにはどうすればよいですか?