Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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_Linux_Bash - Fatal编程技术网

在C中使用命名管道读写同一文件

在C中使用命名管道读写同一文件,c,linux,bash,C,Linux,Bash,更具体地说,该程序应该模拟bash命令cat file | grep$keyword>file。 我所做的是:在父级中,我读取文件中的每个字符,并将它们格式化为行,然后发送到命名管道,然后在子级中,将包含关键字的行写入原始文件 但是,在尝试从原始文件读取第二个字符时,我收到一个分段错误,我认为这是因为父级正在等待子级写入原始文件,而不是读取所述文件的内容 任何关于实现/解释错误发生原因的帮助都将非常有用 #include <stdio.h> #include <string.h

更具体地说,该程序应该模拟bash命令
cat file | grep$keyword>file
。 我所做的是:在父级中,我读取文件中的每个字符,并将它们格式化为行,然后发送到命名管道,然后在子级中,将包含关键字的行写入原始文件

但是,在尝试从原始文件读取第二个字符时,我收到一个分段错误,我认为这是因为父级正在等待子级写入原始文件,而不是读取所述文件的内容

任何关于实现/解释错误发生原因的帮助都将非常有用

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>

char key[20], *c,line[40];
int fd,fd_r,fd_w,fd_fr,fd_fw,counter=0;

int main(){

pid_t pid;
mkfifo("fifo1",0777);
fgets(key,10,stdin);

int k=0;

if ((pid=fork()) < 0)
        perror("err_fork");

if(pid){ //PARENT

        printf("%d\n",fd_r=open("prog.c",O_RDONLY));
        printf("%d\n",fd_fw=open("fifo1",O_WRONLY));
        while(read(fd_r,c,1)){
                line[k++]=(*c);
                while(read(fd_r,c,1) && ((*c)!='\n'))
                        line[k++]=(*c);
                line[k]=0;
                write(fd_fw,line,strlen(line)+1);
                memset(line,0,sizeof(line));
        }
        close(fd_r);
        close(fd_fw);
}
else{   //CHILD
        printf("%d\n",fd_w=open("prog.c",O_WRONLY));
        printf("%d\n",fd_fr=open("fifo1",O_RDONLY));
        while(read(fd_fr,line,sizeof(line))){
                c=strstr(line,key);
                if(c)
                        write(fd_w,line,strlen(line)+1);
        }
        close(fd_w);
        close(fd_fr);
}

unlink("fifo1");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
字符键[20],*c,第[40]行;
int fd,fd_r,fd_w,fd_fr,fd_fw,计数器=0;
int main(){
pid_t pid;
mkfifo(“fifo1”,0777);
fgets(图例10,标准DIN);
int k=0;
如果((pid=fork())<0)
perror(“err_fork”);
if(pid){//PARENT
printf(“%d\n”,fd_r=open(“prog.c”,O_RDONLY));
printf(“%d\n”,fd_fw=open(“fifo1”,O_WRONLY));
while(读(fd_r,c,1)){
行[k++]=(*c);
while(读(fd_r,c,1)&(*c)!='\n'))
行[k++]=(*c);
行[k]=0;
写入(fd_fw,行,strlen(行)+1);
memset(line,0,sizeof(line));
}
关闭(fd_r);
关闭(fd_-fw);
}
else{//CHILD
printf(“%d\n”,fd_w=open(“prog.c”,O_WRONLY));
printf(“%d\n”,fd_fr=open(“fifo1”,O_RDONLY));
while(读取(fd_fr,line,sizeof(line))){
c=strstr(线路、键);
如果(c)
写入(fd_w,行,strlen(行)+1);
}
关闭(fd_w);
关闭(fd_fr);
}
取消链接(“fifo1”);
}

您正在分段错误,因为您试图将一个字节读入
c
。但是,
c
是一个未初始化的全局指针,因此它等于
NULL
。因此,尝试在该位置读取数据是对内存的无效使用

你要做的是申报

char c;
然后

read(fd_r,&c,1)

您知道bash命令
cat file | grep$keyword>file
基本上不起作用吗?通常,它只会截断文件。如果你真的愿意,我想你可以模仿它的破碎,但这有什么意义呢?而且,
while(read(…)
不是一种很好的方法,因为在发生错误的情况下,
read()
返回
-1
,这是非零的,因此将导致循环继续,即使
c
不包含新数据。如果不需要区分错误和EOF,则可以使用
while(read(…)>0)
在关闭文件之前,子文件需要截断文件。否则,文件的结尾仍有未被覆盖的行。@NateEldredge这不会模拟这种中断,因为它在打开输出文件时不使用
O_TRUNC
。它是全局的,因此初始化为NULL。但事实上,你无法读懂它。