我的练习有问题:
在C中编写一个创建子项的程序,在父与子之间,将使用管道进行双向通信。他的父亲将阅读一个文件(其名称将被提供给用户),并将向孩子发送信件。
孩子将使用'a'计算从开始的单词数;如果数字是,是否X的单词,X,以'a'开头大于5,那么孩子将创建自己的孩子(孙子)。企业的孙子将以您认为可能的方式发送X 数字的祖父 * 并退出。 [通过推论:如果数字X小于6,那么孩子就会退出,而'将是祖父母'也会退出。]
这是我到目前为止所做的事情;请帮帮我......
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd1[2], fd2[2], pid, status,sum=0, i;
char gram[100], x;
char buff[100];
char rev[1000];
FILE *fp;
if (pipe(fd1) == -1) { /* Create a pipe */
perror("pipe");
exit(1);
}
pid = fork();
switch (pid)
{
case -1:
perror ("Fork error\n");
exit(99); // in case of error
case 0:
close(fd1[1]);//Close the writing side
rev[1000]= read(fd1[0], buff, 1000); /* Read from the pipe */
/*for (i=0; i< 1000 ; i++)
{
rev[i] = read(fd1[0], buff, sizeof(buff));
}*/
while( rev[i] != '\0')
{
if (buff[i] == 'a' )
{ sum++;
i++;
}
if (rev[i] == "")
{
if (rev[i+1]) //elenxei to epomeno tou kenou
{
sum++;
i++;
}
}
i++;
}
printf("%d", sum);
exit(0);
default:
printf("dwse arxeio\n");
scanf("%s", gram);
close(fd1[0]);//Close the reading side
fp = fopen (gram,"r");
getc(fp);
fclose(fp);
write(fd1[1], buff, sizeof(buff)+1);
close(fd1[1]);//Close the writing side
wait(&status); // waits till the child process ends
}
}
答案 0 :(得分:1)
您可能希望查看popen。 它启动一个子进程并返回一个FILE *,你可以使用它来读取/写入childs stdin / stdout。
答案 1 :(得分:1)
让我们调用GP(对于祖父母),PP(对于父进程)和GC(对于孙子)这三个进程。概括地说,我认为你需要做的是:
与此同时,上面的第2步创建了PP,他必须做一些工作:
现在你有GP和GC了;请记住,GC几乎是PP的精确副本,并且(特别是)GC和PP一样知道X的值。所以,GC也做了一些工作:
GC的第3步确保GP从第8步中醒来。
作为工业设计,没有必要创建GC; PP可以很好地完成GC的工作。作为一项家庭作业,它通过了集合。关键的见解在上面的评论中:
问题的关键在于如何从孙子到祖父的沟通。好消息是,孙子继承了孩子们打开的管道。
其他关键步骤是关闭管道未使用的末端并关闭管道,此时无需再编写。没有这些关闭,进程很容易陷入死锁。例如,如果GP无法关闭RP的写入端,那么从RP读取时它永远不会获得EOF,因为有一个进程仍然可以写入RP - 而且该进程是GP!
答案 2 :(得分:0)
rev[1000]= read(fd1[0], buff, 1000); /* Read from the pipe */
你想用左值来完成什么?
首先,rev
被声明为具有1000个元素,因此rev[1000]
是缓冲区溢出...
其次,我建议您查看read()
手册页的“返回值”部分。它返回接收的字节数(可能小于您指定的第三个参数),或者在文件结束时为0,或者在失败时为负。它将使用实际数据填写buff
的内容。我不确定你的代码中你期望系统调用的行为是什么,但在我看来并不像你正确使用它。
你想做这样的事情:
int r;
r = read(fd1[0], buff, sizeof(buff));
if (r < 0) { /* TODO: Handle error */ }
else if (r == 0) { /* TODO: Handle EOF */ }
else { /* TODO: Handle the fact that buff now contains 'r' bytes */ }