【问题标题】:Cannot get every line of file with pipes无法使用管道获取文件的每一行
【发布时间】:2017-02-21 21:19:06
【问题描述】:

我正在尝试读取文件并返回与关键字与子进程匹配的行,并将它们传达给父进程,顺序无关紧要。

我的第一个问题是:是否可以只使用一个管道或者第一个完成的进程会关闭管道?

我的第二个问题是我为每个孩子创建了一个管道,但父母仍然没有读取所有这些,只是显示了与第一个文件中的关键字匹配的所有行和第二个文件的第一行匹配并停止。(我只尝试了 2 个文件,但这不是问题)

假设所有文件都可以正常打开和关闭。我检查了所有打开的文件,pipe() 和 fork()。其余的不检查。

我的代码如下:

#include "commons.h"
//efmalloc is error-free malloc

int main(int argc, char *argv[]){
    int numargs = argc-1;
    int fds[numargs][2];
    pid_t n;

    for (int i = 0; i < numargs; i++) 
        pipe(fds[i]);
    for(int i = 0; i < argc-1;i++){
        n = fork();
        if(n==0){
            close(fds[i][0]);//closing the read end of the pipe for the children
            FILE * fs = fopen(argv[i+1],"r");
            //// SETTING UP THE PARAMETERS FOR READING ////
            char * outputdata = (char*) efmalloc(400*sizeof(char));
            *outputdata = '\0';
            char * line = NULL;
            size_t len = 0;
            int read = getline(&line, &len, fs);
            int currentline = 1;
            ////    END OF READINGS SETUP ////

            while (read >= 0) {
                if(strstr(line,"keyword") != NULL) {
                    strcat(outputdata,argv[i+1]);
                    strcat(outputdata,line);
                    strcat(outputdata,"\0");
                    //Write the data in the pipe in here
                    write(fds[i][1],outputdata,(strlen(outputdata)+1));
                    *outputdata = '\0';
                }
                read = getline(&line, &len, fs);
                currentline++;
                }
            free(outputdata);
            fclose(fs);
            close(fds[i][1]);   //now closing the write end of the pipe
            exit(0);
        }
    }
    /***** PARENT PROCESS *****/
    if(n!=0) {
        for (int index = 0; index < numargs; index++)
            close(fds[index][1]);
        char * readmsg = (char*)efmalloc(BUFFER_SIZE*sizeof(char));
        for(int j = 0; j < numargs; j++){
            int bytes = read(fds[j][0],readmsg,BUFFER_SIZE);
            while(bytes>0){
                readmsg[bytes] = 0;
                printf("%s\n", readmsg);
                bytes = read(fds[j][0],readmsg,BUFFER_SIZE);
            }
        }
        for(int i = 0; i < numargs;i++)
                wait(NULL);
    }
    return 0;
}

【问题讨论】:

  • 将代码拆分为函数。这将使调试更容易。

标签: c file pipe child-process


【解决方案1】:

我看到了几个小问题,还有两个大问题:

  • getline()read() 都返回 ssize_t,而不是 int。它们相同。
  • strcat(outputdata,"\0"); 什么都不做。如果outputdata 已经正确终止,则不需要,如果outputdata 尚未正确终止,则为未定义行为。
  • 您没有为readmsg 中的'\0' 终止符提供足够的空间 - 您最多可以读取BUFFER_SIZE 字节,但readmsg[BUFFER_SIZE] = 0; 在分配的缓冲区之外。这是未定义的行为。
  • 您不能确定您的所有数据实际上都适合outputdata。无论实际能装多少,你都会在那儿塞得越来越多。如果您超出outputdata,您将再次处于未定义的行为中。

【讨论】:

  • 我被告知文件的行最多 256 个字符,文件名最多 64 个字符,我分配了 400 个,所以绰绰有余。谢谢,我会纠正他们。
猜你喜欢
  • 2023-02-15
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
相关资源
最近更新 更多