0

txt ファイル内の文字をカウントし、子プロセスを使用して文字をカウントし、金額を出力するプログラムがあります。親は、ファイル内の行を while ループで子にフィードするだけです。プログラムは、ファイルを開き、1 行ずつ読み取り、子プロセスが正しい量を出力する場合に機能します。

しかし、子プロセスが金額を返し、代わりに親が文字数を書き出すように変更したいと思います。しかし、私がそれをやろうとすると、プログラムはファイル内の実際の文字数の代わりに 1153416175 を与えてくれます。なぜこうなった?

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 100

int main(int argc, char *argv[]) {
    int fds[2]; /* file descriptors */
    int child; /* child process */
    int n; /* size of line in file */
    int count, alphacount, total=0; /* used in loop for counting chars in line */
    int read_bytes; /* amount of bytes read in read function */
    char line[MAXLINE];
    FILE *fp;
    char *str;

    if (argc < 2) {
        printf("Format: './rakna <filename>'.\nThe file should have the .txt extension.\n");
        exit(1);      
    } else {
        if (pipe(fds) < 0) {
            perror("Can't open pipe\n");
            exit(1);
        }
        child = fork();
        if (child==-1) {
            perror("fork error");
            exit(1);
        }

        /* child that reads chars and returns amount */
        if(child == 0)      
        {
            /* close(fds[1]);  child process close input of pipe Used to be before ..*/
            /* count chars through read */
            while (read_bytes = read(fds[0], line, sizeof(line)) > 0) {
                /* check if line is received */
                if (read_bytes < 0) {
                    perror("Can't read line");
                    exit(1);
                }
                /* count chars in the line */
                else {
                    count=0;
                    alphacount=0;
                    while (line[count] != '\0')
                    {
                        /* counting chars from 'a' to 'z' */
                        if (line[count] >= 'a' && line[count] <= 'z')
                            alphacount++;
                        /* counting chars from 'A' to 'Z' */
                        else if (line[count] >= 'A' && line[count] <= 'Z')
                            alphacount++;
                        count++;
                     }
                     /* adding the nr of chars in line to total */
                     total += alphacount;
                }
            }
            write(fds[1], &total, sizeof(total)); /* passing total nr of chars to parent */
            close(fds[0]); /* closing output part of pipe */
            exit(0); /* ending child process */
        }

        /* parent that sends chars to child-reader and writes out amount */
        else
        {
            /* close(fds[0]);  Parent process close output of pipe */
            fp = fopen(argv[1], "r");
            if (fp == 0) {
                perror("Could not read the file.\n");
                exit(1);
            }
            while (fgets(line, MAXLINE, fp) != NULL) {
                n = strlen(line);
                if (n >= 0) {
                    line[n]='\0';
                    if (write(fds[1], line, n) != n) {
                        perror("write error in pipe");
                        exit(1);
                    }
                }
                else {
                    perror("problem with fgets");
                    exit(1);
                }
            }

            int nrofchars;
            read_bytes = read(fds[0], &nrofchars, sizeof(nrofchars));
            printf("The file has %d nr of chars between a-z\n", nrofchars); //<-- Here it f**ks up, it gives me 1153416175
            close(fds[1]); /* closing input part of pipe */
            wait(NULL); /* waits for child to read end of file */ 
        }
        return 0;
    }
}
4

1 に答える 1

1

パイプは双方向通信ではなく、単方向であり、fd[0] が読み取り側、fd[1] が書き込み側です。

あなたのコードは双方向として1つのパイプを使用しています(双方向になると仮定してFDの終了をコメントアウトしました)。そのため、未定義の動作が発生しています。

双方向が必要な場合は、2 つのパイプが必要です :-) または、socketpair(2) を使用して双方向 IPC fds を作成できます。

さらにヘルプが必要な場合は、コメントをドロップしてください。

于 2013-03-24T02:57:48.267 に答える