如何在C语言中编写和读取命名管道?

10
我有两个程序(write.c和read.c)。我想要从标准输入连续写入命名管道,并在另一端读取它(并将其写入标准输出)。我已经做了一些工作,但它没有正常工作。另一端的程序会按照错误的顺序读取或读取特殊字符(因此它会读取更多的内容?)。我还想能够将命名管道的输出与某个字符串进行比较。
无论如何,这里是两个文件的代码:
write.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFFSIZE 512
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }

void main()
{
    int fd, n;

    char buf[BUFFSIZE];


    mkfifo("fifo_x", 0666);
    if ( (fd = open("fifo_x", O_WRONLY)) < 0)
        err("open")

    while( (n = read(STDIN_FILENO, buf, BUFFSIZE) ) > 0) {
        if ( write(fd, buf, strlen(buf)) != strlen(buf)) { 
            err("write");
        }
    }
    close(fd);
}

read.c:

#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFSIZE 512
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }

void main()
{
    int fd, n;
    char buf[BUFFSIZE];

    if ( (fd = open("fifo_x", O_RDONLY)) < 0)
        err("open")


    while( (n = read(fd, buf, BUFFSIZE) ) > 0) {

        if ( write(STDOUT_FILENO, buf, n) != n) { 
            exit(1);
        }
    }
    close(fd);
}

输入示例:

hello how are you
123 
test

错误输出示例:

hello how are you
b123
o how are you
btest
 how are you
b

另一个输入的示例:

test
hi

输出:

test
hi
t
1个回答

6
读取后修改的缓冲区不是一个有效的C字符串,因此:
write(fd, buf, strlen(buf)) != strlen(buf) // write.c

是未定义的行为。您应该这样做:

write(fd, buf, n) != n

因为你使用read()读取了n个八位字节。有趣的是,你在read.c中这样做,但在write.c中没有。
n的类型必须是ssize_t而不是int,请参考man read
main()函数必须返回一个int类型的值,请声明main函数原型

2
哇,我一开始其实就写对了,但因为不知道什么原因改了,谢谢。 - mythic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接