【发布时间】:2020-01-31 22:43:42
【问题描述】:
我正在尝试通过按退格键来清除文本,我在非规范模式下使用 termios。我创建了一个条件语句,当用户按下退格键时,它应该通过返回一个字符来删除前一个字符。
但是当我按 Backspace 而不是删除字符时,它会在该行打印 ^?。
我不想使用规范模式。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#define MAX_COMMANDS 1000
#define MAX_LENGTH 200
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
void run(char inp[]) {
system(inp);
}
int main() {
//65 = UP
//66 = DOWN
//Backspace = 127
int ch;
char str[MAX_COMMANDS][MAX_LENGTH];
init_keyboard();
int i = 0;
int j = 0;
while(ch != 'q') {
if(kbhit()) {
ch = readch();
if (ch == 127) {
const char delbuf[] = "\b \b";
write(STDOUT_FILENO, delbuf, strlen(delbuf));
}
if (ch == 10) {
run(str[i]);
i++;
j = 0;
} else {
str[i][j] = ch;
j++;
}
}
}
close_keyboard();
exit(0);
}
void init_keyboard() {
tcgetattr(0, &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= (ECHO | ECHOE | ~ICANON);
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard() {
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit() {
char ch;
int nread;
if (peek_character != -1) {
return 1;
}
new_settings.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0, &ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if (nread == 1) {
peek_character = ch;
return 1;
}
return 0;
}
int readch() {
char ch;
if (peek_character != -1) {
ch = peek_character;
peek_character = -1;
return ch;
}
read(0, &ch,1);
return ch;
}
【问题讨论】:
-
您可能会发现 this question of mine 在处理 termios 原始输入时很有用。