uffer整条线路。如果通过管道输送stdin,则预期EOF。是否使用类似于if(ngetc(c)=-1)的Handle\EOF\u或IOError()@chux No,如果(ngetc&c)==0)handle_EOF(),您将使用因为read在EOF上
uffer整条线路。如果通过管道输送stdin,则预期EOF。是否使用类似于if(ngetc(c)=-1)的Handle\EOF\u或IOError()@chux No,如果(ngetc&c)==0)handle_EOF(),您将使用因为read在EOF上,c,linux,stdin,polling,C,Linux,Stdin,Polling,uffer整条线路。如果通过管道输送stdin,则预期EOF。是否使用类似于if(ngetc(c)=-1)的Handle\EOF\u或IOError()@chux No,如果(ngetc&c)==0)handle_EOF(),您将使用因为read在EOF上返回0,但如果(ngetc(&c)
uffer整条线路。如果通过管道输送
stdin
,则预期EOF。是否使用类似于if(ngetc(c)=-1)的Handle\EOF\u或IOError()
@chux No,如果(ngetc&c)==0)handle_EOF(),您将使用
因为read
在EOF
上返回0
,但如果(ngetc(&c)<0)处理其他错误(),则使用
检查是否存在任何其他类型的错误。@谢谢您的回复。我只是有一些问题,你是说我将永远无法以我所说的方式读取fgets()调用后stdin中留下的数据?我也试着用fgetc()代替read(),但那也不起作用。你能解释一下为什么fgetc()也不起作用吗?@JohnVulconshinz是的,我是说你永远不能用你所说的方式使用fgets。ISO C标准没有给您提供解决方法,使用POSIX标准绕过它需要您使用文件描述符。@dlutxx感谢您的回复。你说它读缓冲区是什么意思?我认为fgets()只需要处理终端行缓冲区。@JohnVulconshinzfgets
将消耗整个行(将它们存储在缓冲区中并在后续读取时返回),而不仅仅是2个字符
struct pollfd pollfds;
pollfds = STDIN_FILENO;
pollfds.events = POLLIN;
poll(pollfds, 1, 0);
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
int ngetc(char *c)
{
struct pollfd pollfds;
pollfds.fd = STDIN_FILENO;
pollfds.events = POLLIN;
poll(&pollfds, 1, 0);
if(pollfds.revents & POLLIN)
{
//Bonus points to the persons that can tell me if
//read() will change the value of '*c' if an error
//occurs during the read
read(STDIN_FILENO, c, 1);
return 0;
}
else return -1;
}
//Test Situation:
//Try to read a character left in stdin by an fgets() call
int main()
{
int ret = 0;
char c = 0;
char str[256];
//Make sure to enter more than 2 characters so that the excess
//is left in stdin by fgets()
fgets(str, 2, stdin);
ret = ngetc(&c);
printf("ret = %i\nc = %c\n", ret, c);
return 0;
}
fcntl (0, F_SETFL, O_NONBLOCK);
ssize_t
ngetc (char *c)
{
return read (0, c, 1);
}
#define ngetc(c) (read (0, (c), 1))
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
int main(int argc, char *argv[])
{
struct termios t;
tcgetattr(0, &t);
t.c_lflag &= ~ICANON;
tcsetattr(0, TCSANOW, &t);
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
printf("Starting loop (press i or q)...\n");
for (int i = 0; ; i++) {
char c = 0;
read (0, &c, 1);
switch (c) {
case 'i':
printf("\niteration: %d\n", i);
break;
case 'q':
printf("\n");
exit(0);
}
}
return 0;
}