getch 在没有 initscr 的情况下无法工作
getch not working without initscr
我完成了 NCURSES 的 Documentation。我不明白如果我在没有 initscr 的情况下使用 getch 那么为什么这个程序不工作。有没有其他方法可以在不清除屏幕的情况下获取箭头键输入(initscr 做的)。
#include <ncurses.h>
#include <unistd.h>
int main()
{
int ch;
//initscr();
//raw();
//keypad(stdscr, TRUE);
//noecho();
while(1)
{
ch = getch();
switch(ch)
{
case KEY_UP:
printw("\nUp Arrow");
break;
case KEY_DOWN:
printw("\nDown Arrow");
break;
case KEY_LEFT:
printw("\nLeft Arrow");
break;
case KEY_RIGHT:
printw("\nRight Arrow");
break;
}
if(ch == KEY_UP)
break;
}
//endwin();
}
getch
等同于 wgetch(stdscr)
。它假定屏幕已经初始化。 ncurses(任何 curses 实现)必须做一些事情才能使 wgetch
可用:
- 阅读终端说明
- 初始化终端I/O模式
- 分配一个屏幕来绘制。
最后一个是因为 wgetch
在读取之前对调用它的 window 执行了 wrefresh
。
您可以使用 newterm with filter
to avoid clearing the screen, and doing line-oriented input. The filter
program in ncurses-examples 演示如何执行此操作。
或者,您可以通过 termios
中的 tcsetattr
更改终端属性。如果您在 canonical mode
(需要换行才能开始该过程)和 non-canonocal mode
(按键绰绰有余)之间循环。
以下程序的工作方式如下 - 进程等待用户输入。如果按下向上箭头键,它会打印 'Arrow key pressed' 并退出。如果按下其他东西,它会等待用户按下 Enter
然后打印用户输入。打印输入后退出。
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
struct termios oldt, newt;
char ch, command[20];
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
while(1)
{
ch = getchar();
if (ch == '3')
{ printf("Arrow key\n"); ch=-1; break;}
else if(ch == -1) // by default the function returns -1, as it is non blocking
{
continue;
}
else
{
break;
}
}
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch,stdin);ith
putchar(ch);
scanf("%s",command);
printf("\n%s\n",command);
return 1;
}
return 0;
}
我有一个没有 ncurses 的解决方案
您可以这样使用 simple-getch:
t_key keys[] = {
{"[A", K_UP},
{"[B", K_DOWN},
{"[D", K_LEFT},
{"[C", K_RIGHT},
{NULL, K_UNK},
};
int key;
ch_init();
while ((key = ch_get(keys)) != K_BACK)
{
printf("%d\n", key);
}
ch_end();
keys
数组是将要使用的转义序列列表,(当您在终端中键入箭头键时,它将写入一个转义键,后跟多个字符以定义该键。)
此序列 may/will 在终端之间变化,您应该使用 termcap 正确设置此序列。
我完成了 NCURSES 的 Documentation。我不明白如果我在没有 initscr 的情况下使用 getch 那么为什么这个程序不工作。有没有其他方法可以在不清除屏幕的情况下获取箭头键输入(initscr 做的)。
#include <ncurses.h>
#include <unistd.h>
int main()
{
int ch;
//initscr();
//raw();
//keypad(stdscr, TRUE);
//noecho();
while(1)
{
ch = getch();
switch(ch)
{
case KEY_UP:
printw("\nUp Arrow");
break;
case KEY_DOWN:
printw("\nDown Arrow");
break;
case KEY_LEFT:
printw("\nLeft Arrow");
break;
case KEY_RIGHT:
printw("\nRight Arrow");
break;
}
if(ch == KEY_UP)
break;
}
//endwin();
}
getch
等同于 wgetch(stdscr)
。它假定屏幕已经初始化。 ncurses(任何 curses 实现)必须做一些事情才能使 wgetch
可用:
- 阅读终端说明
- 初始化终端I/O模式
- 分配一个屏幕来绘制。
最后一个是因为 wgetch
在读取之前对调用它的 window 执行了 wrefresh
。
您可以使用 newterm with filter
to avoid clearing the screen, and doing line-oriented input. The filter
program in ncurses-examples 演示如何执行此操作。
或者,您可以通过 termios
中的 tcsetattr
更改终端属性。如果您在 canonical mode
(需要换行才能开始该过程)和 non-canonocal mode
(按键绰绰有余)之间循环。
以下程序的工作方式如下 - 进程等待用户输入。如果按下向上箭头键,它会打印 'Arrow key pressed' 并退出。如果按下其他东西,它会等待用户按下 Enter
然后打印用户输入。打印输入后退出。
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
struct termios oldt, newt;
char ch, command[20];
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
while(1)
{
ch = getchar();
if (ch == '3')
{ printf("Arrow key\n"); ch=-1; break;}
else if(ch == -1) // by default the function returns -1, as it is non blocking
{
continue;
}
else
{
break;
}
}
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch,stdin);ith
putchar(ch);
scanf("%s",command);
printf("\n%s\n",command);
return 1;
}
return 0;
}
我有一个没有 ncurses 的解决方案
您可以这样使用 simple-getch:
t_key keys[] = {
{"[A", K_UP},
{"[B", K_DOWN},
{"[D", K_LEFT},
{"[C", K_RIGHT},
{NULL, K_UNK},
};
int key;
ch_init();
while ((key = ch_get(keys)) != K_BACK)
{
printf("%d\n", key);
}
ch_end();
keys
数组是将要使用的转义序列列表,(当您在终端中键入箭头键时,它将写入一个转义键,后跟多个字符以定义该键。)
此序列 may/will 在终端之间变化,您应该使用 termcap 正确设置此序列。