因此,Linux中的top
命令具有类似实时循环的控制台输出(没有花哨的东西),但它使用非阻塞控制台输入,这不会在命令行中显示键入的字符。它是如何实现的?是否有任何库可用,他们使用线程吗?我需要编写一个使用相同风格的Linux应用程序(通过ssh使用),但我不知道如何处理输入(在单独的线程中使用cin不是解决方案,top
使用了其他方法)。
因此,Linux中的top
命令具有类似实时循环的控制台输出(没有花哨的东西),但它使用非阻塞控制台输入,这不会在命令行中显示键入的字符。它是如何实现的?是否有任何库可用,他们使用线程吗?我需要编写一个使用相同风格的Linux应用程序(通过ssh使用),但我不知道如何处理输入(在单独的线程中使用cin不是解决方案,top
使用了其他方法)。
top
是如何做到的。
ldd /usr/bin/top
显示 libncurses.so.5 => /lib64/libncurses.so.5
。因此,top
使用了 ncurses 库。 - Nikos C.另一个选项,不使用curses:
#include <stdio.h>
//#include <unistd.h>
#include <termios.h>
//#include <sys/ioctl.h>
//#include <sys/time.h>
//#include <sys/types.h>
#include <fcntl.h>
//------------------------------------------------------------------------------
// getkey() returns the next char in the stdin buffer if available, otherwise
// it returns -1 immediately.
//
int getkey(void)
{
char ch;
int error;
struct termios oldAttr, newAttr;
int oldFlags, newFlags;
struct timeval tv;
int fd = fileno(stdin);
tcgetattr(fd, &oldAttr);
newAttr = oldAttr;
oldFlags = fcntl(fd, F_GETFL, 0);
newAttr.c_iflag = 0; /* input mode */
newAttr.c_oflag = 0; /* output mode */
newAttr.c_lflag &= ~ICANON; /* line settings */
newAttr.c_cc[VMIN] = 1; /* minimum chars to wait for */
newAttr.c_cc[VTIME] = 1; /* minimum wait time */
// Set stdin to nonblocking, noncanonical input
fcntl(fd, F_SETFL, O_NONBLOCK);
error=tcsetattr(fd, TCSANOW, &newAttr);
tv.tv_sec = 0;
tv.tv_usec = 10000; // small 0.01 msec delay
select(1, NULL, NULL, NULL, &tv);
if (error == 0)
error=(read(fd, &ch, 1) != 1); // get char from stdin
// Restore original settings
error |= tcsetattr(fd, TCSANOW, &oldAttr);
fcntl(fd, F_SETFL, oldFlags);
return (error ? -1 : (int) ch);
}
int main()
{
int c,n=0;
printf("Hello, world!\nPress any key to exit. I'll wait for 4 keypresses.\n\n");
while (n<4)
{
//printf("."); // uncomment this to print a dot on each loop iteration
c = getkey();
if (c >= 0)
{
printf("You pressed '%c'\n", c);
++n;
}
}
}
很抱歉我不能完全为此负责,因为我多年前从网络上找到了它。我认为我已经稍微改进了一下,但它大部分仍然与我找到它时相同。不幸的是,我没有添加注释表明我在哪里找到它。
newAttr.c_lflag &= ~(ICANON | ECHO);
替换 newAttr.c_lflag &= ~ICANON;
,但你需要改变 getkey()
函数的整个策略,因为 (按照当前的实现) 它保存并无条件地恢复 stdio 终端模式,这将在返回之前重新打开 echo。这个链接展示了如何请求密码(不显示字符)而不使用 curses/ncurses:http://forums.fedoraforum.org/showpost.php?s=da285de869a78cf3e28b7196c6457fc3&p=1516255&postcount=4 - phonetagger