繁体   English   中英

如何在C中正确读取stdin?

[英]How to correctly read stdin in C?

我想用C编写类似sgtpep / pmenu的应用程序。

然后,我开始看一下ncurses库。 我的第一次尝试是能够选择菜单。 如我做ls | ./a.out ls | ./a.out ,它应该能够显示所有文件,并突出显示第一个文件,当我按UPDOWN时 ,它将相应地更改突出显示的其他项目。

完整的代码在这里

该程序没有收到任何按键。 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.outch不断显示-1


UPD2

使用newterm重定向inout的作品。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM