[英]How to output to a file with information from a pipe in C?
我对执行完第二个程序后尝试输出到文件时的错误感到困惑。
说我有以下名称的输入文件:
马蒂·B·海滩7 8
扎卡里湾 惠特克12 23
伊万·桑切斯02 15
吉姆·塔冈加纳9 03
我的程序完成后,它将把学生的姓名转换为他们的用户名,并将其输出到这样的文件中:
mbb0708
zbw1223
is0215
jt0903
目前,按照我的程序的立场,它什么也不输出到文件,并且终端似乎陷入了无限循环,尽管之前对我的转换器程序进行了自我测试,并确保将其正确输出到stdout。
我不确定我在做什么错吗? 第一次使用管道编程。 我知道必须利用读取和写入命令来提取数据,但是使用dup2命令是仅读取命令所必需的吗?
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char** argv)
{
pid_t pid;
int nbytes;
/*Buffer to hold data from pipe*/
char buffer[BUFSIZ + 1];
/*Pipe Information*/
int commpipe[2];
if(pipe(commpipe))
{
fprintf(stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
if((pid = fork()) == -1)
{
fprintf(stderr,"Fork error. Exiting.\n");
exit(1);
}
else if(pid == 0)
{
/*This is the child process. Close our copy of the write end of the file descriptor.*/
close(commpipe[1]);
/* Connect the read end of the pipe to standard input*/
dup2(commpipe[0], STDIN_FILENO);
/*Program will convert the Student's name to their respective names*/
execl("converter","converter",NULL);
/*Exit if failure appears*/
exit(EXIT_FAILURE);
}
else
{
FILE *file;
file = fopen("usernames.txt","a+"); //append a file(add text to a file or create a file it does not exist)
/*Close or copy of the read end of the file descriptor */
//close(commpipe[1]);
nbytes = write(commpipe[1], buffer, BUFSIZ);
//Read from pipe here first?
//Output to usernames.txt the usernames of the user from the pipe.
fprintf(file, "%s", buffer);
/*Wait for the child process to finish*/
waitpid(pid, NULL, 0);
}
return 0;
}
一个问题是,管理器将所有数据发送到转换器后,管理器没有关闭commpipe[1]
。 因此,转换器将永远不会在stdin上获得EOF,因此不会退出。
经理极有可能由于缓冲而没有从转换器获取任何数据。 当不写入终端时,stdio的某些实现使用全缓冲区缓冲(与行缓冲相反)。 一旦解决了先前的错误并关闭了该进程,将刷新stdout。 您还可以考虑在puts行之后添加fflush(stdout)
。
看一下OpenGroup网站,有一个与您相似的示例。 我建议您首先使用一些硬编码的示例。 一旦工作,添加代码以读取和写入结果。
我做了一些小的改动以使示例正常工作:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
int main(int argc, char** argv){
int fildes[2];
const int BSIZE = 100;
char buf[BSIZE];
ssize_t nbytes;
int status;
status = pipe(fildes);
if (status == -1 ) {
/* an error occurred */
printf("Error!\n");
exit(-1);
}
printf("Forking!\n");
switch (fork()) {
case -1: /* Handle error */
printf("Broken Handle :(\n");
break;
case 0: /* Child - reads from pipe */
printf("Child!\n");
close(fildes[1]); /* Write end is unused */
nbytes = read(fildes[0], buf, BSIZE); /* Get data from pipe */
/* At this point, a further read would see end of file ... */
assert(nbytes < BSIZE); /* Prevent buffer overflow */
buf[nbytes] = '\0'; /* buf won't be NUL terminated */
printf("Child received %s", buf);
close(fildes[0]); /* Finished with pipe */
fflush(stdout);
exit(EXIT_SUCCESS);
default: /* Parent - writes to pipe */
printf("Parent!\n");
close(fildes[0]); /* Read end is unused */
write(fildes[1], "Hello world\n", 12); /* Write data on pipe */
close(fildes[1]); /* Child will see EOF */
/* Note that the Parent should wait for a response from the
child here, because the child process will be terminated once
the parent exits */
exit(EXIT_SUCCESS);
}
return 0;
}
据我了解,您的转换器程序从stdin读取行并将其写入stdout。 由于管道是单向实体,因此您需要两个管道与管理器进行通信-一个管道将数据发送到转换器,另一个管道从转换器接收输出。
也许您应该考虑增强转换器以采用(作为可选参数)输入和输出文件的名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.