Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
阅读整个管道-c_C_Pipe_Dup2_Feof - Fatal编程技术网

阅读整个管道-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*
但您提供了of
int
tube[0]
是inetger)类型

/usr/include/stdio.h:828:12:注意:应为“struct FILE*”,但 参数的类型为“int”

因此,第一件事总是读取编译器警告&使用
-Wall
标志编译代码

fgetc(管[0])
不是从
文件描述符读取数据的方法,请使用
read()
系统调用从文件描述符not
fgetc()
读取数据
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);
        }