C-仅读取单个字符时如何检测管道中的EOF?
正如在回答中所解释的,我希望读卡器进程在写卡器进程关闭所有相关文件描述符之后立即捕获C-仅读取单个字符时如何检测管道中的EOF?,c,pipe,eof,file-descriptor,C,Pipe,Eof,File Descriptor,正如在回答中所解释的,我希望读卡器进程在写卡器进程关闭所有相关文件描述符之后立即捕获EOF 但这并没有发生,这个项目最终陷入了一个无休止的循环。 父级等待其子级完成&子级等待EOF发出关闭管道的信号 为什么读卡器进程没有接收到EOF? #包括 #包括 #包括 #包括 #定义字符串以发送“你好,世界!\n” int main(){ int-fd[2],i=0; __pid_t pid; 字符(char);; ssize_t nbytes; 管道(fd); pid=fork(); 如果(pid==-
EOF
但这并没有发生,这个项目最终陷入了一个无休止的循环。
父级等待其子级完成&子级等待EOF
发出关闭管道的信号
为什么读卡器进程没有接收到EOF
?
#包括
#包括
#包括
#包括
#定义字符串以发送“你好,世界!\n”
int main(){
int-fd[2],i=0;
__pid_t pid;
字符(char);;
ssize_t nbytes;
管道(fd);
pid=fork();
如果(pid==-1){
//错误
perror(“错误分叉!”);
返回退出失败;
}否则如果(pid==0){
//孩子
关闭(fd[1]);
而((n字节=读取(fd[0],&_char,1))!=EOF){
如果(n字节==0)
继续;
putchar(_char);
}
关闭(fd[0]);
}否则{
//母公司
关闭(fd[0]);
对于(;;){
_char=STRING_TO_SEND[i++];
写入(fd[1],&_char,1);
如果(_char=='\0')
打破
}
关闭(fd[1]);
关闭(标准文件号);
while(wait(NULL)>0{}
}
返回0;
}
您只是误解了read()
的“文件结束”指示,这对于read()
(在这种情况下,read()返回0)来说意味着没有什么可读的了。但是read()
实际上并没有返回值EOF
。所以你的情况应该是:
while ((nbytes = read(fd[0], &_char, 1)) > 0) {
另外,\uu pid\u t
是C库的内部类型。你不应该用那个;只需使用pid\t
有关详细信息,请参见的手册页。
EOF
是一个常量,通常定义为-1,stdio
(原始系统调用周围的C库缓冲层)用于在函数(如getchar()
)中发出文件结束信号,该函数将返回的字符与文件结束信号合并
read
只需返回0
即可发出文件结束的信号。请注意,如果出现错误,它也可以返回-1(例如,如果读取在读取任何内容之前被信号处理程序中断,则可以获取EINTR
)
因此,您想要的是:
while ((nbytes = read(fd[0], &_char, 1)) > 0){ /*...*/ }
if (0>nread) { /*report error (or maybe repeat if it's EINTR)*/ }
手册页()或文档中的所有内容。
read()
在没有更多数据可读取时返回0
,而不是EOF
(保证为负值,通常为-1
)。如果有错误,您只能从read()
获取-1
;没有更多数据不是错误。那么为什么没有EOF
,当writer进程关闭时,它是fd
?存在文件结束条件,read()
调用通过返回0
告诉您这一点。你忙于忽略它告诉你的东西,所以它会重复自己,但是你的代码没有从read()
所说的东西中学习,所以这个循环持续了很长时间。哦,我明白了!read()
函数在有一些可用数据后开始读取!因此0
字节读取意味着fd
已关闭。非常感谢:)我认为read()
函数甚至在发送任何数据之前就返回0
字节……我不需要n字节(那么:)是的,除非您有兴趣区分“文件结束”条件(read()返回0时)和错误条件(read()返回-1时)。
while ((nbytes = read(fd[0], &_char, 1)) > 0){ /*...*/ }
if (0>nread) { /*report error (or maybe repeat if it's EINTR)*/ }