阅读整个管道-c
我在使用这个代码时遇到了一些困难。 我需要从管道末端获取所有信息。 但是,我有一个错误阅读整个管道-c,c,pipe,dup2,feof,C,Pipe,Dup2,Feof,我在使用这个代码时遇到了一些困难。 我需要从管道末端获取所有信息。 但是,我有一个错误 #include <fcntl.h> #include <stdio.h> #include <stdlib.h> int main(void){ int tube[2]; if(pipe(tube) == -1){ perror("Erreur"); exit(1); } dup2(tube[1],1
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
int tube[2];
if(pipe(tube) == -1){
perror("Erreur");
exit(1);
}
dup2(tube[1],1);
printf("Few lines \n");
printf("of an undefined size. \n");
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
return 0;
}
#包括
#包括
#包括
内部主(空){
int管[2];
如果(管道)=-1){
perror(“Errer”);
出口(1);
}
dup2(管[1],1);
printf(“几行\n”);
printf(“大小未定义。\n”);
而(!feof(管[0])){
炭温度=fgetc(管[0]);
printf(“链:%c\n”,临时);
}
返回0;
}
如果您知道我如何处理此问题,请解释。您使用的函数返回单个字符(fgetc),然后将该值视为printf调用中字符串的指针。您还将该字符存储为指向某个字符的指针的地址,而不是实际的字符,因此当printf读取字符串时,它正在读取一些它不拥有的低内存。fgetc返回字符本身,您需要一个char变量,而不是char* 尝试:
管道
函数返回的是一对int
文件描述符,而不是文件
描述符。这意味着您可以对它们使用read
、write
或close
,但既不能使用fgetc
,也不能使用feof
此外,while(!feof(file))
几乎总是这样,因为标志是在文件末尾读取失败后设置的
这还不是全部。只有当写入端上的所有描述符都关闭时,管道的读取端才会获得EOF。因此,必须关闭或刷新stdout
以确保所有字符都已写入管道,如果尚未关闭stdout,请关闭文件描述符1,然后关闭仍然是管道写入端的文件描述符的tube[1]
因此,您可以将while循环替换为:
close(tube[1]);
fclose(stdout);
while (1) {
char temp;
if (read(tube[0], &temp, 1) < 1) break;
fprintf(stderr, "chaine : %c\n", temp);
}
关闭(管[1]);
fclose(stdout);
而(1){
焦炭温度;
如果(读取(管[0],&temp,1)<1)破裂;
fprintf(标准,“链:%c\n”,临时);
}
它修复了在非文件
上使用feof
和fgetc
导致的SEGFAULT,并确保在读取文件内容之前正确关闭文件的写入端,以获得良好的文件结束状态。但是,我得到了一个SEGFAULT错误?这意味着您没有正确阅读编译器警告。当您执行feof(tube[0])
时,它会显示feof()
预期FILE*
但您提供了ofint
(tube[0]
是inetger)类型
/usr/include/stdio.h:828:12:注意:应为“struct FILE*”,但
参数的类型为“int”
因此,第一件事总是读取编译器警告&使用-Wall
标志编译代码
这fgetc(管[0])
不是从文件描述符读取数据的方法,请使用read()
系统调用从文件描述符notfgetc()
读取数据fgetc()
如果使用fopen()
打开文件,则可以使用
也
像这样使用
dup2(1,tube[1]);/*stdout get duplicated with tube[1] i.e whatever you
write on stdout will be written into write end of pipe*/
下面是一个简单的例子
char temp[100];
int ret = 0;
ret = read(tube[0],temp,sizeof(temp));/*reading from pipe*/
if(ret == -1) {
perror("read");
return 0;
}
else {
temp[ret] = '\0';/*read returns no of items read, so put null
at last otherwise you may get some junk data */
printf("%s",temp);
}
阅读man2read
&man2dup2
了解这些系统调用是如何工作的。如何处理这些问题是现在开始学习如何使用调试器。我不是油嘴滑舌:这是诊断和解决自己问题的一项基本技能,而不必等待互联网上的人帮你解决问题fgetc()
的参数是一个文件*
。您的代码传递一个int
。这引入了未定义的行为。另外,fgetc()
返回int
,而不是char
。最后,关于(!feof())
样式循环是一种糟糕的技术的原因,有很多很好的解释-谷歌会帮你找到一个。我总是会遇到一个错误。但是,是的,这是一个误解(因此我更新了主要帖子)。Thxfeof()和fgetc()都需要指向流的指针,而不是文件描述符。尝试使用fpopen()创建流。如果管道仍然为空,read()
函数将阻止等待内容写入管道,进程通常会挂起。此答案讨论了:您也可以在管道手册页中阅读:
dup2(1,tube[1]);/*stdout get duplicated with tube[1] i.e whatever you
write on stdout will be written into write end of pipe*/
char temp[100];
int ret = 0;
ret = read(tube[0],temp,sizeof(temp));/*reading from pipe*/
if(ret == -1) {
perror("read");
return 0;
}
else {
temp[ret] = '\0';/*read returns no of items read, so put null
at last otherwise you may get some junk data */
printf("%s",temp);
}