在 C 中如何读取进程的输出并将其写入另一个进程的输入?
In C how to read the output of a process and write it in the input of another?
你好,我有一个 C 程序,它基本上假设在 linux 中模拟管道函数,并将读取的字节数写入 .txt 文件中,这样
./a.out cat test : grep -v le : wc -l
我想解决的问题是
为什么在文件中写入相同数量的字节,因为我知道每个进程 returns 数量不同?
这段代码在父进程中执行,并试图通过读取系统调用计算每个输出的字节数,并在下一个进程的写入系统调用中写入输出,以便下一个进程可以使用输出作为他的输入。
假设我有这些管道 a | b | c
此代码将读取 a
的输出并将其写入 b
以便 b
可以将其用作输入等。
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
char str[4096];
int count=0;
int nbChar=0;
while(1){
count=read(apipe[i][0],str,sizeof(str));
nbChar+=count;
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
}else if(count==0)break;
}
char *leInput=(char*)malloc(nbChar*sizeof(char));
strncpy(leInput,str,nbChar);
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
每次通过 while(1)
循环时,您都会读到 str
的开头,而不是您在上一次迭代中离开的地方。所以你正在用下一个阅读覆盖上一个阅读。
您应该在每次循环中逐步复制到 leInput
。然后你可以使用 realloc()
来扩大它以适应新的输入,你可以使用 leInput + nbChar
在你上次完成的地方之后复制。
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
int nbChar=0;
char *leInput = NULL;
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
leInput = realloc((nbChar + count)*sizeof(char));
memcpy(leInput + nbChar, str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
或者,您可以在内循环中写入下一个管道,而不将所有内容收集到 leInput
:
for (int i = 1; i < processes-1; i++) {
int nbChar = 0;
close(apipe[i][1]);
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
write(apipe[i+1][1], str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
close(apipe[i+1][1])
}
你好,我有一个 C 程序,它基本上假设在 linux 中模拟管道函数,并将读取的字节数写入 .txt 文件中,这样
./a.out cat test : grep -v le : wc -l
我想解决的问题是
为什么在文件中写入相同数量的字节,因为我知道每个进程 returns 数量不同?
这段代码在父进程中执行,并试图通过读取系统调用计算每个输出的字节数,并在下一个进程的写入系统调用中写入输出,以便下一个进程可以使用输出作为他的输入。
假设我有这些管道 a | b | c
此代码将读取 a
的输出并将其写入 b
以便 b
可以将其用作输入等。
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
char str[4096];
int count=0;
int nbChar=0;
while(1){
count=read(apipe[i][0],str,sizeof(str));
nbChar+=count;
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
}else if(count==0)break;
}
char *leInput=(char*)malloc(nbChar*sizeof(char));
strncpy(leInput,str,nbChar);
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
每次通过 while(1)
循环时,您都会读到 str
的开头,而不是您在上一次迭代中离开的地方。所以你正在用下一个阅读覆盖上一个阅读。
您应该在每次循环中逐步复制到 leInput
。然后你可以使用 realloc()
来扩大它以适应新的输入,你可以使用 leInput + nbChar
在你上次完成的地方之后复制。
for (int i = 1; i < processes-1; i++) {
close(apipe[i][1]);
int nbChar=0;
char *leInput = NULL;
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
leInput = realloc((nbChar + count)*sizeof(char));
memcpy(leInput + nbChar, str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
write(apipe[i+1][1], leInput, nbChar);
}
或者,您可以在内循环中写入下一个管道,而不将所有内容收集到 leInput
:
for (int i = 1; i < processes-1; i++) {
int nbChar = 0;
close(apipe[i][1]);
while(1){
int count=0;
char str[4096];
count=read(apipe[i][0],str,sizeof(str));
if(count==-1){
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if(count==0) {
break;
}
write(apipe[i+1][1], str, count);
nbChar += count;
}
if(i>0){
fprintf(fp, "%d : %d \n ", i,nbChar);
}
close(apipe[i][0]);
close(apipe[i+1][1])
}