我想在C程序中前后移动光标。我正在读取一个循环中的整行,但是我希望如果按下光标键,屏幕上的光标会改变位置,而不会阻塞循环。我试过了,getwch()但它阻止了呼叫者,直到按下它为止。我正在寻找的是一种类似于bash提示的行为。我正在阅读与此类似的代码:
getwch()
while (TRUE) { printf("%s", PROMPT); fgets(input, 1024, stdin); do_something(input); }
我正在尝试上面的功能像readline(PROMPT)在readline.h库上一样
readline(PROMPT)
readline.h
使用termios和控制台代码(兼容VT100-非便携式):
termios
#include <stdio.h> #include <string.h> #include <termios.h> #include <unistd.h> #define cursorforward(x) printf("\033[%dC", (x)) #define cursorbackward(x) printf("\033[%dD", (x)) #define KEY_ESCAPE 0x001b #define KEY_ENTER 0x000a #define KEY_UP 0x0105 #define KEY_DOWN 0x0106 #define KEY_LEFT 0x0107 #define KEY_RIGHT 0x0108 static struct termios term, oterm; static int getch(void); static int kbhit(void); static int kbesc(void); static int kbget(void); static int getch(void) { int c = 0; tcgetattr(0, &oterm); memcpy(&term, &oterm, sizeof(term)); term.c_lflag &= ~(ICANON | ECHO); term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &term); c = getchar(); tcsetattr(0, TCSANOW, &oterm); return c; } static int kbhit(void) { int c = 0; tcgetattr(0, &oterm); memcpy(&term, &oterm, sizeof(term)); term.c_lflag &= ~(ICANON | ECHO); term.c_cc[VMIN] = 0; term.c_cc[VTIME] = 1; tcsetattr(0, TCSANOW, &term); c = getchar(); tcsetattr(0, TCSANOW, &oterm); if (c != -1) ungetc(c, stdin); return ((c != -1) ? 1 : 0); } static int kbesc(void) { int c; if (!kbhit()) return KEY_ESCAPE; c = getch(); if (c == '[') { switch (getch()) { case 'A': c = KEY_UP; break; case 'B': c = KEY_DOWN; break; case 'C': c = KEY_LEFT; break; case 'D': c = KEY_RIGHT; break; default: c = 0; break; } } else { c = 0; } if (c == 0) while (kbhit()) getch(); return c; } static int kbget(void) { int c; c = getch(); return (c == KEY_ESCAPE) ? kbesc() : c; } int main(void) { int c; while (1) { c = kbget(); if (c == KEY_ENTER || c == KEY_ESCAPE || c == KEY_UP || c == KEY_DOWN) { break; } else if (c == KEY_RIGHT) { cursorbackward(1); } else if (c == KEY_LEFT) { cursorforward(1); } else { putchar(c); } } printf("\n"); return 0; }