我想寫一個像sgtpep/pmenu在C的應用程序。如何正確讀取C中的stdin?
然後我開始看看ncurses
庫。我第一次嘗試可以選擇菜單。比如當我做ls | ./a.out
時,應該可以顯示所有文件,並突出顯示第一個,當我按UP或DOWN時,它會相應地改變高亮不同的項目。
完整的代碼是here。
該程序沒有收到任何按鍵。 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
不乾淨,所以我使用fflush(stdin)
後fgets
,但它的結果相同。
那麼從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
,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();
我懷疑這是一個ncurses問題,實際上並不是一個C問題。用於在POSIX系統上讀取C的最低級API實際上不是C'fgets'方法,而是POSIX'read'系統調用。不過,我認爲這不是問題所在。我認爲問題是終端不處於「原始模式」。我不記得如何將終端設置爲原始模式,我認爲這取決於終端,我非常確定ncurses有一個初始化函數來處理這種事情。 –
我在print_menu()中看不到「refresh()」。有關編寫ncurses應用程序的詳細信息,請看這裏:http://invisible-island.net/ncurses/ncurses-intro.html – TonyB
@TonyB謝謝!這是一個複製和粘貼錯誤...我改變了代碼結構來清除它,但忘記添加'refresh()'。 – delta