我正在尝试编写2个程序,这些程序将使用fifo管道相互通信。 我使用了示例here(第5.2节),但我将mknod更改为mkfifo并尝试将gets更改为fgets。 这是代码(一个写入fifo的程序):
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h> /*mkfifo, open */
#include <sys/wait.h>
#include <sys/stat.h> /* mkfifo, open */
#include <fcntl.h> /*open */
#define FIFO_PATH "/home/hana/Desktop"
#define BUFFER_SIZE 300
int main()
{
char buffer[BUFFER_SIZE];
int fd;
int wStatus;
mkfifo(FIFO_PATH, 666);
printf("waiting for readers\n");
fd = open(FIFO_PATH, O_RDWR);
while (fgets(buffer, BUFFER_SIZE, fd), !feof(stdin))
{
if ((wStatus = write(fd, buffer, strlen(buffer))) == -1)
perror("write");
else
printf("speak: wrote %d bytes\n", wStatus);
}
return 0;
}
我收到编译错误:传递fgets参数3使得指针来自整数。 所以fgets期待FILE *而不是文件描述符。 我该怎么办?改变一些东西,以便fgets工作?使用其他功能?
我正在用gcc(ansi,pedantic)编译。
由于
答案 0 :(得分:1)
whjm的答案是你的错误诊断的原因,但我想你可能意味着
fgets(buffer, BUFFER_SIZE, stdin)
// ^^^^^
从管道读取然后立即将相同的东西写回管道是没有意义的。此外,如果您从未阅读过stdin
,feof(stdin)
永远不会成真。
另外,使用fgets只检查null结果然后在循环外部,检查eof:
while (fgets(...) != NULL)
{
...
}
if (!feof(stdin))
{
// error handling
}
答案 1 :(得分:0)
mkfifo()
只是在文件系统中创建特殊节点。你可以自由地以任何方式打开它。实际上有两种选择 - POSIX&#34;非缓冲&#34; I / O:open()/write()/read()
或标准缓冲I / O:fopen()/fread()/fwrite()
。第一个家族使用文件描述符,而第二个家族使用所谓的文件流:FILE
。您无法自由混合这些API。只需选择一个并坚持下去。
与低级非缓冲I / O相比,标准I / O库提供了一些有用的额外功能。与您尝试使用的fgets()
一样。在这种情况下,使用标准流并将open()
替换为:
FILE* stream = fopen(FIFO_PATH, "r+");
因此程序将使用FILE*
而不是普通文件描述符。同时write()
需要更改为fwrite()
,然后紧跟fflush()
以保证写入的数据传递到FIFO。
P.S。如果有必要,可以包装&#34;包装&#34; open()
(或其他)使用标准FILE*
返回的低级描述符。见fdopen()
。但这非常类似于使用标准I / O API以及无法使用fopen()
打开的特殊文件对象的解决方法。