C语言 Unix 管道正在接受输入但不显示输出



我正在尝试为一个 C 程序创建一个管道,该程序采用 pre.c 并使用子进程处理它,并采用 sort.c 并将其作为父进程进行处理。当我执行管道可执行文件时,我被提示输入必要的输入,但是当我 ctrl-d 时,没有显示输出。当我运行 ./pre | ./排序更多相同时 - 没有输出。当我单独运行这些单独的可执行文件时,它们似乎工作正常。知道发生了什么来阻止输出被正确处理吗?

前 C:

#include <stdio.h>
typedef struct{
char  name[4];
int   population;
} State;
enum { MAX_STATES = 10 };
int main()
{
State myStates[MAX_STATES];
int i, j;
// Function to read in multiple lines (up to 10) of user input; loop 
// controls in place, detects format problems, prevents string buffer 
// overflows.
for (i = 0; i < MAX_STATES; i++)
{
if (scanf("%2s %dn", myStates[i].name, &myStates[i].population) != 2)
break;
}
printf("n");
// Function to output (stdout) array of State structs that exceed 10 
// population. 
for(j = 0; j < i; j++)
{
if(myStates[j].population >= 10)
{
printf("%s %dn", myStates[j].name, myStates[j].population);
}
}
return 0;
}

sort.c:

#include <stdio.h>
#include <string.h>
typedef struct{
char  name[3];
int   population;
} State;
enum { MAX_STATES = 10 };
int main()
{
State myStates[MAX_STATES];
int i, 
j,
k, 
count = 0;
char temp[3];
while( scanf("%s%d", myStates[i].name, &myStates[i].population)!= EOF)
i++;
count = i;
// for(i = 0; i < MAX_STATES; i++)
// {
//     if (scanf("%2s %dn", myStates[i].name, &myStates[i].population) != 2)
//         break;
//     count++;
// }
printf("n");
// Function to sort necessary input 
for(j = 0; j < (count-1); j++)
{
strcpy(temp, myStates[j].name);
for(k = j + 1; k < count; k++)
{
if(strcmp(myStates[j].name, myStates[k].name) > 0)
{
strcpy(myStates[j].name, myStates[k].name);
strcpy(myStates[k].name, temp);
}
}
}
for( i=0; i < count; i++)
{
printf("%sn", myStates[i].name);
}
return 0;
}

管道.c:

#include <stdio.h>
int main()
{
int pid;
int fd[2];
pid = pipe(fd);
fork();
if(pid < 0) // error case
printf("could not create pipen");
else if(pid == 0)
{
// Child Process
close(1);
dup(fd[1]);
close(fd[0]);
close(fd[1]);
execvp("./pre", 0);
}
else
{
// Parent Process
close(0);
dup(fd[0]);
close(fd[0]);
close(fd[1]);
execvp("./sort", 0);
}
return 0;
}

输入:

$ ./pipe
TX 32
RI 3
CA 53

输出:

修复了代码 - 但sort.c现在使用qsort()而不是您的自制排序,这在更大的数据集上对我不起作用。

这些程序在运行macOS Sierra 10.12.6的Mac上使用GCC 7.1.0和命令行进行干净的编译,如下:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes 
>     pre.c -o pre
$

需要进行许多小的更改才能使其工作 - 删除变量,添加标头等。

pipe.c的关键变化之一是从fork()捕获pid,而不是pipe()

pre.c

#include <stdio.h>
typedef struct
{
char name[3];
int population;
} State;
enum { MAX_STATES = 10 };
int main(void)
{
State myStates[MAX_STATES];
int i, j;
for (i = 0; i < MAX_STATES; i++)
{
if (scanf("%2s %dn", myStates[i].name, &myStates[i].population) != 2)
break;
}
for (j = 0; j < i; j++)
{
if (myStates[j].population >= 10)
{
printf("%s %dn", myStates[j].name, myStates[j].population);
}
}
return 0;
}

sort.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char name[3];
int population;
} State;
static int cmp(const void *v1, const void *v2)
{
const State *s1 = (State *)v1;
const State *s2 = (State *)v2;
return strcmp(s1->name, s2->name);
}
enum { MAX_STATES = 10 };
int main(void)
{
State myStates[MAX_STATES];
int count = 0;
for (int i = 0; i < MAX_STATES; i++)
{
if (scanf("%s %d", myStates[i].name, &myStates[i].population) != 2)
break;
count++;
}
qsort(myStates, count, sizeof(myStates[0]), cmp);
for (int i = 0; i < count; i++)
{
printf("%sn", myStates[i].name);
}
return 0;
}

pipe.c

#include <stdio.h>
#include <unistd.h>
int main(void)
{
int fd[2];
if (pipe(fd) != 0)
{
fprintf(stderr, "could not create pipen");
return(1);
}
int pid = fork();
if (pid < 0)
{
fprintf(stderr, "could not forkn");
return(1);
}
else if (pid == 0)
{
close(1);
if (dup(fd[1]) != 1)
return(1);
close(fd[0]);
close(fd[1]);
char *arg1[] = { "./pre", 0 };
execv(arg1[0], arg1);
fprintf(stderr, "failed to execute %sn", arg1[0]);
return(1);
}
else
{
close(0);
if (dup(fd[0]) != 0)
return(1);
close(fd[0]);
close(fd[1]);
char *arg2[] = { "./sort", 0 };
execv(arg2[0], arg2);
fprintf(stderr, "failed to execute %sn", arg2[0]);
return(1);
}
return 0;
}

示例数据

CA 39250017
TX 27862596
FL 20612439
NY 19745289
IL 12801539
PA 12784227
OH 11646273
GA 10310371
NC 10146768
MI 9928301

(人口数据来自维基百科。

./pre < states的输出

CA 39250017
TX 27862596
FL 20612439
NY 19745289
IL 12801539
PA 12784227
OH 11646273
GA 10310371
NC 10146768
MI 9928301

./pre < states | ./sort输出

CA
FL
GA
IL
MI
NC
NY
OH
PA
TX

./pipe < states输出

CA
FL
GA
IL
MI
NC
NY
OH
PA
TX

最新更新