我正在尝试写2个程序,将彼此交谈使用先进先出管道。我使用了示例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,学究)一起编译。
谢谢
发布于 2017-08-30 22:33:00
mkfifo()只是在文件系统中创建了特殊的节点。你可以自由地以任何方式打开它。实际上有两种选择-- POSIX“非缓冲”I/O:fopen()/fread()/fwrite()或标准缓冲I/O: POSIX。第一个系列操作文件描述符,而第二个系列使用所谓的文件流:FILE。您不能随意混合这些API。只需选择一个并坚持下去。与低级的非缓冲I/O相比,标准I/O库提供了一些有用的额外功能,比如您正在尝试使用的fgets()。在这种情况下,合理的做法是使用标准流,并将open()替换为:
FILE* stream = fopen(FIFO_PATH, "r+");因此,程序将使用FILE*而不是普通文件描述符。此外,需要立即将write()更改为fwrite(),然后再更改为fflush(),以确保写入的数据被传递到FIFO.
备注:在必要的情况下,可以用标准FILE*“包装”由open()(或其他东西)返回的低级描述符。参见fdopen()。但是,使用标准I/O处理不能用fopen()打开的特殊文件对象很像一种变通方法。
发布于 2017-08-30 22:31:27
来自whjm的答案是导致错误诊断的原因,但我认为您的意思可能是
fgets(buffer, BUFFER_SIZE, stdin)
// ^^^^^ 从管道中读取数据,然后立即将相同的内容写回管道,这是不合理的。而且,如果你从来没有读过stdin,那么feof(stdin)永远不会是真的。
此外,对于fgets,只需检查null结果,然后在循环外部检查eof:
while (fgets(...) != NULL)
{
...
}
if (!feof(stdin))
{
// error handling
}https://stackoverflow.com/questions/45962906
复制相似问题