我试图编写一个程序,从文件中读取一些文本并将其打印到屏幕上。父级将读取文件的内容将其写入n个管道,子级将读取它然后打印它。
到目前为止,这就是我所拥有的:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
int main (void)
{
pid_t pid;
char c;
FILE *fd;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j;
for(i=0; i<N_CHILDREN; i++)
{
pipe(p[i]);
}
fd=fopen("123.txt","r");
for(j=0; j < N_CHILDREN;j++)
{
pid = fork ();
if (pid == 0)
{
close (p[j][1]);
while(read(p[j][0], &fd,sizeof(buf)) > 0)
printf("\n%c",&fd);
}
if (pid < 0)
{
//Fork Failed
fprintf (stderr, "Fork failure.\n");
return EXIT_FAILURE;
}
if ( pid > 0) //Parent
{
close (p[j][0]);
write(p[j][1], fd ,sizeof(buf));
}
}
}
问题是它没有真正从文件中读取内容。我试过发送一串字符而不是从文件中读取它并按预期工作,两个孩子都打印了一次消息并且程序结束了。
有什么想法吗?阅读完手册后,我仍然无法看到问题所在。
答案 0 :(得分:3)
您使用Unix文件描述符I /混淆C标准I / O流(使用fopen()
创建;使用fprintf()
等编写,使用fscanf()
等读取) O(由open()
或pipe()
等人创建,与write()
等人一起写,与read()
等人一起阅读)
标准I / O函数采用不透明FILE *
作为句柄; Unix I / O函数将文件描述符(小int)作为句柄。
一旦你理解了概念上的差异,我相信你会意识到这一点
FILE *fd = ...
read(..., &fd, ...);
正在读取指向文件的指针 - 不是非常有用: - )
答案 1 :(得分:1)
这里有几个问题:
read
&fd
来使用FILE*
功能。这个函数需要一个指向要打印的“缓冲区”的指针,我想这里buf
。fopen
失败。read
(在儿童中)的返回值,因为它是您获得的有效数据量。因此,在此之后您必须打印的数据量(到标准输出)。所以这是一个示例代码,请参阅内部的评论:
// put here all the needed includes (see manpages of functions)
// it is better to create a function for the child: the code
// is easier to read
// the child just get the file descriptor to read (the pipe)
void child(int fd) {
char buf[100]; // buffer to store data read
int ret; // the number of bytes that are read
// we read from 'fd', into 'buf'. It returns the number of bytes
// really read (could be smaller than size). Return <=0 when over
while((ret = read(fd, buf, sizeof(buf))) > 0) {
// write the 'ret' bytes to STDOUT (which as file descriptor 1)
write(1, buf, ret);
}
}
int main (void) {
pid_t pid;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j, ret;
int fdi;
// create the pipes
for(i=0; i<N_CHILDREN; i++) {
if (pipe(p[i]) == -1) {
perror("pipe"); // ALWAYS check for errors
exit(1);
}
}
// open the file (with 'open' not 'fopen', more suitable for
// reading raw data
fdi = open("123.txt",O_RDONLY);
if (fdi < 0) {
perror("open"); // ALWAYS check for errors
exit(1);
}
// just spawn the children
for(j=0; j < N_CHILDREN;j++) {
pid = fork();
if (pid < 0) {
perror("fork"); // ALWAYS check for errors
exit(1);
}
if (pid == 0) { // child
close(p[j][1]); // close the writing part
child(p[j][0]); // call child function with corresp. FD
exit(0); // leave : the child should do nothing else
}
}
// don't need that part
for(j=0; j<N_CHILDREN; j++) {
close(p[j][0]); // close the read-part of pipes
}
// need to read file content, see comment in child() function
while ((ret = read(fdi, buf, sizeof(buf))) > 0) {
// write the data to all children
for(j=0; j<N_CHILDREN; j++) {
write(p[j][1], buf , ret); // we write the size we get
}
}
// close everithing
for(j=0; j<N_CHILDREN; j++) {
close(p[j][1]); // needed, see text after
}
close(fdi); // close read file
return(0); // main returns a int, 0 is "ok"
}
在不需要或结束时,您必须关闭管道的每个部分。在文件描述符打开之前,读取将阻止该过程。仅当最后一个写入对应关闭时,读取返回&lt; = 0。
注意:1。正确使用读/写功能2.检查错误3.从文件读取并写入管道4.处理读取的有效数据量(ret
变量)这样你就可以编写(“屏幕”或其他文件描述符适当的数据。
答案 2 :(得分:0)
据我所知,你没有读到任何关于buf的内容。