提问人:ztarky 提问时间:4/24/2018 最后编辑:Jonathan Lefflerztarky 更新时间:6/16/2019 访问量:5785
读取整个管道 - c
Read an entire pipe - c
问:
我在这段代码上遇到了一些困难。 我需要从管道末端获取所有信息。 但是,我收到一个段错误。
#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;
}
如果您知道我如何处理这个问题,请解释。
答:
你正在使用一个返回单个字符 (fgetc) 的函数,然后将该值视为指向 printf 调用中字符串的指针。您还将该字符存储为指向字符的指针的地址,而不是实际字符,因此当 printf 读取您的字符串时,它会读取一些它不拥有的低内存。fgetc 返回字符本身,你需要一个 char 变量,而不是 char*。
尝试:
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
评论
函数返回的是一对 int
文件描述符,而不是 1。这意味着您可以在它们上使用 、 或,但不能使用 、 或 。pipe
FILE
read
write
close
fgetc
feof
此外,(几乎)总是错误的,因为该标志是在未成功的读取到达文件末尾后设置的。while(!feof(file))
这还不是全部。只有当写入端的所有描述符都关闭时,您才能在管道的读取端获得 EOF。因此,您必须关闭或刷新以确保所有字符都已写入管道,如果尚未关闭 stdout,则关闭文件描述符 1,并关闭它仍然是管道写入端的文件描述符。stdout
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);
}
它修复了由在非 上使用 和 引起的 SEGFAULT,并确保在读取文件内容之前正确关闭文件的写入端,以获得良好的文件结束条件。feof
fgetc
FILE
评论
read()
但是,我收到一个段错误。?这意味着您没有正确阅读编译器警告。当你这样做时,它说期望,但你已经提供了(是inetger)类型。feof(tube[0])
feof()
FILE*
int
tube[0]
/usr/include/stdio.h:828:12:注意:应为“struct FILE *”,但 参数的类型为“int”
因此,第一件事是始终阅读编译器警告并使用标志编译代码。-Wall
这不是从中读取数据的方式,使用系统调用从文件描述符中读取数据不是。 如果您用 打开了文件,则可以使用。fgetc(tube[0]);
file descriptor
read()
fgetc()
fgetc()
fopen()
也
dup2(tube[1],1); /* this is not expected one which you want*/
像这样使用
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);
}
阅读 & 以了解这些系统调用的工作原理。man 2 read
man 2 dup2
上一个:FEOF过早成为现实
下一个:PHP码计数额外数字
评论
fgetc()
FILE *
int
fgetc()
int
char
while (!feof())