编辑: 因此,通过一些额外的调试,EOF 已成功写入管道(我知道这一点是因为我进行了测试以确保 write()
函数是在 produceStdin
上返回 0。HOWEVER 当从同一管道读取 时,它说我遇到了 EOF(好)但是 EOF 的值元素等于 255(而不是通常的 -1)。有谁知道为什么会这样???
我正在尝试编写这个程序,但是当我遇到来自标准输入的 EOF 时,它并没有向管道写入 -1。无论出于何种原因,当试图通过管道传递 EOF 时,都会写入垃圾,因此所有后续进程都陷入无限循环。
除了在 printOut()
函数中打印数组的那些打印语句之外,所有这些打印语句都是我在尝试调试它(由于 fork 而无法使用调试器)
此外:其中一些评论已被回收,因此如果您看到提到“缓冲区”,那是因为 这是以前使用缓冲区而不是管道编程的。
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_CHARS 81 //80 chars + null-terminator
#define NUM_CHILDREN 3
void produceStdin(int writePipe);
void child1(int readPipe, int writePipe);
void child2(int readPipe, int writePipe);
void printOut(int readPipe);
int main(int argc, char const *argv[])
{
int i,pipe1[2],pipe2[2],pipe3[2];
pid_t childPid;
if(pipe(pipe1)==-1||pipe(pipe2)==-1||pipe(pipe3)==-1)
{
fprintf(stderr, "Error in creating pipe");
}
//despite what it looks like only four children are being forked,
// all to the same parent. The children get called to their respective
//functions where they get terminated before getting to fork themselves.
for(i=0;i<NUM_CHILDREN;i++)
{
childPid=fork();
switch (childPid) {
case -1:
perror("fork() failed. Aborting.");
exit(EXIT_FAILURE);
case 0:
switch (i) {
case 0:
close(pipe1[0]); //close pipe1 read (since we're reading from stdin)
close(pipe2[0]); //close pipe2
close(pipe2[1]);
printf("right before calling stdin i=%d\n",i);
produceStdin(pipe1[1]); //write to pipe1
break;
case 1:
close(pipe1[1]); //close pipe1 write
close(pipe2[0]); //close pipe2 read
close(pipe3[0]); //close pipe3
close(pipe3[1]);
printf("right before calling child1 i=%d\n",i);
child1(pipe1[0], pipe2[1]); //read from pipe1, write to pipe2
break;
case 2:
close(pipe1[0]); //close pipe1
close(pipe1[1]);
close(pipe2[1]); //close pipe2 write
close(pipe3[0]); //close pipe3 read
printf("right before calling child2 i=%d\n",i);
child2(pipe2[0], pipe3[1]); //read from pipe2, write to pipe3
break;
default:
break;
}
default:
if(i==2)
{
close(pipe1[1]); //close pipe1
close(pipe1[0]);
close(pipe2[1]); //close pipe2
close(pipe2[0]);
close(pipe3[1]); //close pipe3 write
printOut(pipe3[0]); //read from pipe3 read
}
break;
}
}
return 0;
}
void produceStdin(int writePipe)
{
int c=0;
while(c!=EOF)
{
c=fgetc(stdin);
write(writePipe, &c, sizeof(char)); //writing EOF here is where the problem starts I believe
}
printf("Got EOF in ProdStdin\n");
printf("EOF has a value of: %d",c);
exit(0);
}
void child1(int readPipe, int writePipe)
{
int c=0;
while(c!=EOF)
{
read(readPipe,&c,sizeof(char));
// printf("Child1 got a char from pipe1: %c\n",c);
if(c=='\n')
{
c=' '; //test for newline
}
write(writePipe, &c, sizeof(char));
}
exit(0);
}
void child2(int readPipe, int writePipe)
{
int c=0;
int c2=0;
while(c!=EOF && c2!=EOF)
{
read(readPipe, &c, sizeof(char));
// printf("Child2 got a char from pipe2: %c\n",c);
if(c=='*')
{
read(readPipe, &c2, sizeof(char)); //if c is a * remove another char
if(c2=='*')
{
c='^'; //if c2 is a * then put a ^ on buffer3
write(writePipe,&c,sizeof(char));
}
else
{
write(writePipe,&c,sizeof(char));
write(writePipe,&c2,sizeof(char));
}
}
else
{
write(writePipe,&c,sizeof(char));
}
}
exit(0);
}
void printOut(int readPipe)
{
int c=0,numChars=0;
char output[MAX_CHARS];
while (c!=EOF)
{
read(readPipe, &c, sizeof(char));
// printf("PrintOut got a char from pipe3: %c\nnumChars= %d\n",c,numChars);
if (numChars==MAX_CHARS-2)
{
printf("%s\n",output);
memset(output, '\0', sizeof(char)*MAX_CHARS);
numChars=0;
}
output[numChars]=c;
numChars++;
}
printf("ABOUT TO EXIT PRINTOUT()\n");
exit(0);
}
最佳答案
备选方案 传递通过管道读取内容的 2 字节版本,以便接收端可以区分 char 和 EOF。
int c = 0;
while(c!=EOF) {
c = fgetc(stdin);
short sc = (short) c;
// `sc` will _typically_ have the values -1 (EOF) and 0,1,2,... 255.
write(writePipe, &sc, sizeof(sc));
}
int c=0;
int c2=0;
while(c != EOF && c2 != EOF) {
short sc;
if (sizeof(sc) != read(readPipe, &sc, sizeof(sc))) handle_error();
// `sc` will _typically_ have the values -1 (EOF) and 0,1,2,... 255.
c = sc;
...
原始建议的答案。
c
不会变成 EOF,直到 所有字符都被读取。
使用:
// while(c!=EOF) {
// c=fgetc(stdin);
// write(writePipe, &c, sizeof(char));
// }
while((c = fgetc(stdin)) != EOF) {
write(writePipe, &c, sizeof(char));
}
应该评估 read(readPipe, &c, sizeof(char));
的返回值,而不是寻找成为 EOF 的 c
。 EOF 不适合 char
。
// int c=0;
// int c2=0;
// while(c!=EOF && c2!=EOF) {
// read(readPipe, &c, sizeof(char));
char c=0;
char c2=0;
while(1 == read(readPipe, &c, sizeof(char))) {
关于c - 管道上的 EOF 正在打印垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19389395/