[英]How to correctly read stdin in C?
我想用C编写类似sgtpep / pmenu的应用程序。
然后,我开始看一下ncurses
库。 我的第一次尝试是能够选择菜单。 如我做ls | ./a.out
ls | ./a.out
,它应该能够显示所有文件,并突出显示第一个文件,当我按UP或DOWN时 ,它将相应地更改突出显示的其他项目。
完整的代码在这里 。
该程序没有收到任何按键。 mvprintw(n+1, 0, "%d\\n", ch);
循环内始终打印-1
。
然后,我删除不相关的代码,并获得最小的示例。
#include <stdio.h>
char buf[100];
int main(int argc, char **argv) {
int ch;
while (fgets(buf, sizeof(buf), stdin)) puts(buf);
ch = getch();
printf("%d\n", ch);
ch = getch();
printf("%d\n", ch);
ch = getch();
printf("%d\n", ch);
ch = getch();
printf("%d\n", ch);
return 0;
}
ch
始终为-1
。 我怀疑stdin
不是干净的,因此我在fgets
之后使用fflush(stdin)
,但结果相同。
那么从stdin
读取的正确方法是什么?
UPD1
#include <stdio.h>
char buf[100];
int main(int argc, char **argv) {
int ch;
while (fgets(buf, sizeof(buf), stdin)) puts(buf);
fflush(stdin);
ch = getchar();
printf("%d\n", ch);
ch = getchar();
printf("%d\n", ch);
ch = getchar();
printf("%d\n", ch);
ch = getchar();
printf("%d\n", ch);
return 0;
}
我已经修改了程序,因此它不再与ncurses
有关,而是在运行ls | ./a.out
ls | ./a.out
, ch
不断显示-1
。
UPD2
使用newterm
重定向in
和out
的作品。
FILE *fd = fopen("/dev/tty", "r+");
set_term(newterm(NULL, fd, fd)); // instead of initscr()
noecho();
cbreak();
keypad(stdscr, TRUE);
print_menu(cur, n);
while (true) {
ch = getch();
if (ch == KEY_UP || ch == 'k') --cur;
else if (ch == KEY_DOWN || ch == 'j') ++cur;
cur = (cur + n) % n;
print_menu(cur, n);
}
endwin();
如果要以这种方式从stdin切换到curses,则在阅读完标准输入后,必须打开终端设备,例如/dev/tty
。 打开终端后,您可以使用newterm
初始化curses(与initscr
不同,它具有输入/输出流的initscr
)。
有关示例,请参见ncurses测试程序或对话框 。
curses是stdin的替代方法。
C模型是用户在控制台中编写一行,从而为其提供了行编辑功能。 他可以退格并使用箭头键在直线上移动,直到满意为止。 然后他按Enter键,程序将获得整行。 然后程序会对其进行处理,通常会提示输入下一行。
curses接管了键盘,因此可以用作键盘-您可以进行一些空间侵略者游戏,其中“ z”表示“左”,“ x”表示“右”。 因此,您不应该尝试同时从stdin进行读取,您将获得字符,但是curses系统将以奇怪的方式与它们交互。 通过诅咒专门阅读。
在上一个程序中,您最多读取EOF的输入。 因此,后续输入为EOF。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.