我们可以使用 fgets()、fputs()、feof() 等函数来执行操作吗?像我们用于普通文件一样的fifo文件?

Posted

技术标签:

【中文标题】我们可以使用 fgets()、fputs()、feof() 等函数来执行操作吗?像我们用于普通文件一样的fifo文件?【英文标题】:can we perform the operation using functions like fgets(), fputs(), feof(),etc. for the fifo file like we use for the normal file? 【发布时间】:2019-11-08 07:21:35 【问题描述】:

我有一个任务,我必须使用 fifo 将文件从客户端进程传输到服务器进程。我尝试将 fifo 文件作为我们在系统中创建的其他文件来处理。它编译没有任何错误,但它没有正确执行。有人可以给我一个关于计算机系统内的fifo文件结构的想法吗?它有哪些过程和功能?到目前为止,我知道如何使用 create()、read()、write()、open() 函数来处理 fifo 文件。另外,如果有人能帮助我更正,我将不胜感激我的程序?

我的客户端和服务器程序如下:-

客户程序:-

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

int main()

int fd;
char *myfifo ="/tmp/myfifo";
char str[80];
FILE *fp;
char filename[20];
printf("\nEnter filename: ");
gets(filename);
mkfifo(myfifo,0666);
fp = fopen(filename,"r");
if(fp == NULL)

   printf("\nError opening the file");
   exit(1);

fd = open(myfifo, O_WRONLY);
while(fgets(str,80,fp)!=NULL)

  write(fd,str,strlen(str)+1);

close(fd);
fclose(fp);
return 0;

客户程序:-

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

int main()

    int fd1;
    char *myfifo ="/tmp/myfifo";
    char str1[80], filename[20];

    FILE *fp1, *fp2;
    fd1= open(myfifo, O_RDONLY);
    fp1 = fopen(filename,"r");
    fp2 = fopen(filename,"w");
    while(!feof(fp1))
    
        read(fd1,str1,strlen(str1)+1);
        fputs(str1,fp2);
    
     return 0;



   

【问题讨论】:

【参考方案1】:

是的,但是您的程序中存在一些小问题。在第一个:

write(fd, str, strlen(str)+1);

有点不合常规。这会将字符串及其字符串结尾分隔符 (\0) 发送到 fd。通常不会对字符串执行此操作,strlen(str) 可能就是您想要的。

在第二个:

fp1 = fopen(filename,"r");
fp2 = fopen(filename,"w");

filename 没有被赋值,所以这两个打开几乎肯定会失败。当他们这样做时,他们返回一个 NULL 指针,所以第一次尝试使用它们:

while(!feof(fp1))

可能会导致段违规。另外,无论如何你都不使用 fp1,所以如果 feof(fp1) 返回 1,它总是返回 1。你希望这个循环基于 fifo 耗尽的时间,这意味着它里面没有数据,没有人有它打开写。所以稍微改变一下这个程序就会产生:

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

int main()

    int fd1;
    char *myfifo ="/tmp/myfifo";
    char str1[80];
    ssize_t n;
    fd1= open(myfifo, O_RDONLY);
    while ((n=read(fd1,str1,sizeof str1)) > 0)
    
        fwrite(str1, 1, n, stdout);
    
    return 0;

虽然这组更改有效,但它并没有解决您的另一个问题,即关于使用带有管道的 stdio 函数。答案是肯定的,这是您的第二个程序的另一个功能重写:

#include<stdio.h>

int main()

    char *myfifo ="/tmp/myfifo";
    FILE *fp;
    int c;
    if ((fp = fopen(myfifo, "r")) != NULL) 
    while ((c = getc(fp)) != EOF) 
        putchar(c);
    
    fclose(fp);
    
    return 0;

另外,首先是 stdio 的关键位:

...
FILE *fi = fopen(myfifo, "a");
while(fgets(str,80,fp)!=NULL)

  fputs(str, fi);

fclose(fi);
...

和第二个一样,循环可以用 getc、putc 实现。 一般的改进可能是这样的函数:

ssize_t FCopy(FILE *in, FILE *out) 
    int c;
    ssize_t len = 0;
    while ((c = getc(in)) != EOF) 
        len++;
        if (putc(c, out) != c) 
            return -len;
        
    
    return len;

ssize_t FileAppend(char *from, char *to) 
    FILE *in, *out;
    ssize_t n = 0;
    if ((in = fopen(from, "rb")) != NULL) 
        if ((out = fopen(to, "ab")) != NULL) 
            n = FCopy(in, out);
            fclose(out);
         else 
            n = -1;
        
        fclose(in);
     else 
        n = -1;
    
    return n;

所以你的 main 看起来更像:

...
   char filename[80];
   printf("Enter a file to store the data in: ");
   if (fgets(filename, sizeof filename, stdin)) 
       filename[strlen(filename)-1] = '\0';
       if (FileAppend(myfifo, filename) < 0) 
           printf("Error: could not save data to %s\n", filename);
       
   
....

【讨论】:

非常感谢 mevets!但是如何将 fifo 文件的内容:myfifo 转移到我必须在客户端进程中创建的新文件中。因为我的问题是将文件从服务器进程传输到客户端进程

以上是关于我们可以使用 fgets()、fputs()、feof() 等函数来执行操作吗?像我们用于普通文件一样的fifo文件?的主要内容,如果未能解决你的问题,请参考以下文章

fgets与fputs

C-字符数组的存储, 字符指针,  fputs, fgets

C 语言文件操作 ( 按照文本行的方式读写文件 | fgets 函数 | fputs 函数 )

C语言 文件读写 fputs 函数

C语言fputs fgets fputc fgetc fscanf fprintf及fopen操作的整理

c语言中fgets 、fputs、fread、fscanf、fseek的区别和作用