我有一个聊天客户端,它以原始终端模式接收输入,但我不知道在这种模式下处理输入。我需要知道两件事:
\n
?此外,在\n
上刷新的逐字符读取循环示例真的很棒。谢谢!
答案 0 :(得分:6)
我建议使用GNU readline library。它负责获取输入线的繁琐工作,并允许用户使用退格键,左箭头和右箭头等编辑其行,并使用向上箭头调用旧命令,甚至使用^ R搜索旧命令, Readline安装了类似Linux的典型unix类发行版,但是如果你没有它,你可以找到它here
编辑:这是一个最小的readline示例:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
int main(int argc, char ** argv)
{
while(1)
{
char * line = readline("> ");
if(!line) break;
if(*line) add_history(line);
/* Do something with the line here */
}
}
使用gcc -o test test.c -lreadline -lncurses进行编译。
如果您不能使用readline,则getline是另一种选择:
#include <stdio.h>
int main()
{
char * line = NULL;
size_t len;
while(getline(&line, &len, stdin) >= 0)
printf("I got: %s", line);
}
如果即使getline是不可接受的,也可以使用fgets。它不会动态分配合适大小的缓冲区,因此会截断太长的行。但至少它是标准C:
#include <stdio.h>
int main()
{
char buf[1000];
while(fgets(buf, sizeof(buf), stdin)
printf("I got: %s, line);
}
答案 1 :(得分:5)
在Windows中有一个非常有用的函数kbhit()但不幸的是在linux中没有。可以有多种方法。我们将为linux创建自己的kbhit()方法。当在输入缓冲区中检测到某些内容时,kbhit()将返回非零值,否则它将返回0并传递。简单来说,它是非阻塞的。只要结果为true,则调用getch()方法获取该按下的键。
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
void changemode(int);
int kbhit(void);
int main(void)
{
int ch;
changemode(1);
while ( !kbhit() ); // Waiting for some keyboard input.
// something has been detected. now get that.
ch = getchar();
printf("\nGot %c\n", ch);
changemode(0);
return 0;
}
void changemode(int dir)
{
static struct termios oldt, newt;
if ( dir == 1 )
{
tcgetattr( STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
}
else
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}
int kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}