简体   繁体   English

如何在 C++ 中修复管道

[英]How to fix a pipe in C++

I am still a novice when it comes to UNIX and C++, creating a sort of unruly mess.当谈到 UNIX 和 C++ 时,我仍然是一个新手,造成了一种难以驾驭的混乱。

My task is to create a pipe, fork the process, let the parent process read in characters from a text file, pass those characters through the pipe to the child process, have the child process convert the case of the character from uppercase to lowercase or vice versa, then output the character.我的任务是创建一个管道,分叉进程,让父进程从文本文件中读取字符,将这些字符通过管道传递给子进程,让子进程将字符的大小写从大写转换为小写或反之亦然,然后输出字符。

When I run this code I see the following error: (null) Segmentation Fault (Core Dumped)当我运行此代码时,我看到以下错误: (null) Segmentation Fault (Core Dumped)

When I put sleeper print statements into the program, I saw that the program located the file, forked properly, but while the child process began, the parent wouldn't start.当我将 sleeper print 语句放入程序时,我看到程序找到了文件,正确地分叉,但是当子进程开始时,父进程不会启动。 Any help is greatly appreciated.任何帮助是极大的赞赏。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

int main()
{

    FILE* fh;
    fh = fopen("data.txt", "r");
    int pipeID[2];
    pipe(pipeID);
    int len;

    if (fork() == 0) //this is the filter process
    {
        char filter[len];
        read(pipeID[0], filter, len);
        if (filter[0] >= 'a' && filter[0] <= 'z')
            filter[0] = filter[0] - 32;
        else if (filter[0] >= 'A' && filter[0] <= 'Z')
            filter[0] = filter[0] + 32;
        printf("%s", filter[0]);
    }

    else {
        char ch;
        char* toFilter;
        for (ch = getc(fh); ch != EOF; ch = getc(fh)) {
            printf("%s", ch);
            write(pipeID[1], &ch, len);
        }
    }
}

Why are you printing characters and using string specifiers?为什么要打印字符并使用字符串说明符? You are probably accessing some not allowed memory locations.. Try using %c instead of %s.您可能正在访问一些不允许的内存位置。尝试使用 %c 而不是 %s。

I see one major problem with several other glitches.我发现一个主要问题与其他几个故障有关。 Based on your code, I modified like this (still not good), and please see comments prefacing #<num> :根据您的代码,我进行了这样的修改(仍然不好),请参阅#<num>评论:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

int main()
{
    FILE* fh;
    fh = fopen("data.txt", "r");
    int pipeID[2];
    pipe(pipeID);
    /* int len; */  // #1 `len` is not needed

    if (fork() == 0)
    {
        close(pipeID[1]); // #2-1 usually we close unused end of pipe
        char filter[1024];
        int read_len;
        while ((read_len = read(pipeID[0], filter, sizeof(filter))) > 0) // #3 see below
        {
            for (int i = 0; i < read_len; ++i)
            {
                if (filter[i] >= 'a' && filter[i] <= 'z')
                    filter[i] = filter[i] - 32;
                else if (filter[i] >= 'A' && filter[i] <= 'Z')
                    filter[i] = filter[i] + 32;

                printf("%c", filter[i]);
            }
        }
    }
    else {
        close(pipeID[0]); // #2-2 same as #2-1
        char ch;
        /* char* toFilter; */ // #4 remove unused variable
        while ((ch = getc(fh)) != EOF) { // #5 a while is better than for
            printf("%c", ch);   // #6 %s -> %c
            write(pipeID[1], &ch, sizeof(char)); // #7 len -> sizeof(char)
        }
    }
}

The biggest problem is in the #3 part.最大的问题是在#3 部分。 You may think once you write to a pipe, the other end of pipe will immediately read the data.您可能认为一旦写入管道,管道的另一端会立即读取数据。 However, you can't rely on exactly one char is written and then read.但是,您不能完全依赖写入然后读取一个字符。 So you need read as much as possible alternately until an EOF indicating the end of writing.因此,您需要尽可能多地交替读取,直到出现表示写入结束的EOF Therefore, I changed the code as #3.因此,我将代码更改为 #3。

As for other problems, they are not really faulty.至于其他的问题,其实也算不上什么毛病。 I think these are caused by carelessness.我认为这些都是粗心造成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM