将命令行参数传递给子进程并对其进行计数

时间:2010-03-06 00:35:22

标签: c

我希望父进程将参数传递给main(),并通过以argv [1]开头的管道一次一个地将字符发送到子进程,并继续执行其余的参数。打电话给每个角色写字。)

我希望子进程计算父进程发送给它的字符,并打印出从父进程收到的字符数。子进程不应以任何方式使用main()的参数。

我做错了什么?我需要使用exec()?

输出不正确:

    ~ $ gc a03
gcc -Wall -g a03.c -o a03
~ $ ./a03 abcd ef ghi

child: counted 12 characters
~ $

这是程序..

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{

    int length = 0;
    int i, count;

    int     fdest[2];          // for pipe
    pid_t   pid;              //process IDs
    char    buffer[BUFSIZ];



    if (pipe(fdest) < 0)          /* attempt to create pipe */
        printf("pipe error");

    if ((pid = fork()) < 0)  /* attempt to create child / parent process */

    {
        printf("fork error");
    } 


    /* parent process */
    else if (pid > 0) {      
        close(fdest[0]);

        for(i = 1; i < argc; i++)    /* write to pipe */
        {
            write(fdest[1], argv[i], strlen(argv[1]));
        }

        wait(0);

    } else {   

        /* child Process */
        close(fdest[1]);

        for(i = 0; i < argc; i++)
        {
            length +=( strlen(argv[i])); /* get length of arguments */
        }

        count = read(fdest[0], buffer, length);
        printf("\nchild: counted %d characters\n", count);

    }

    exit(0);

}

4 个答案:

答案 0 :(得分:3)

你说过“子进程不应该以任何方式使用main()的参数”。但是,我发现您的子进程正在使用argc。这不会打败你的限制吗?

你还说你想要“为每个角色写一个电话”。您当前的实现使用一个调用来为每个参数写入,而不是每个字符。这是一个错字吗?如果没有,你会想要使用更像这样的东西:

char nul='\0', endl='\n';
for (a=1; a < argc; ++a) {
    for (c=0; c < strlen(argv[a]); ++c) {
        write(fdest[1], &argv[a][c], 1);
    }
    write(fdest[1], &nul, 1);
}
write(fdest[1], &endl, 1);

这将一次写入一个字符,每个参数作为以NULL结尾的字符串和最后的换行符。换行符仅用作标记,表示没有更多数据要发送(并且可以安全使用,因为您不会在CLI参数中传递换行符。)

子进程只需要是一个循环,逐个读取传入的字节,如果字节不是'\0''\n',则递增计数器。当它读取换行符时,它会突破输入处理循环并报告计数器的值。

答案 1 :(得分:1)

您在此处有错误:

write(fdest[1], argv[i], strlen(argv[1]));

你应该使用strlen(argv[i]),或者告诉write()读取argv [i]的空格并调用未定义的行为。

请注意,您只需调用一次read()。当你调用read()时,父节点可能只写了一个argv []。或2.或其中任意数量。

答案 2 :(得分:0)

在这里:

for(i = 1; i < argc; i++)    /* write to pipe */  
{  
    write(fdest[1], argv[i], strlen(argv[1]));  
}

strlen(argv[1])实际上应该是strlen(argv[i])

答案 3 :(得分:0)

问题出在这里

write(fdest[1], argv[i], strlen(argv[1]));

请注意,这是argv[1]的strlen,它应该是argv[i]。您实际上在此循环中引用了argv[2]argv[3]的结尾

你实际上是在编写strlen(“abcd”)* 3个字符,这是12个字符