簡體   English   中英

我們可以使用 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?

我有一個任務,我必須使用 fifo 將文件從客戶端進程傳輸到服務器進程。我嘗試將 fifo 文件作為我們在系統中創建的其他文件來處理。 它編譯沒有任何錯誤,但它沒有正確執行。有人可以給我一個關於計算機系統內的fifo文件結構的想法嗎? 它有哪些進程和功能?到目前為止,我知道如何使用 create()、read()、write()、open() function 獲取 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;



   }

是的,但是您的程序中存在一些小問題。 在第一個:

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

有點不合常規。 這會將字符串及其字符串結尾分隔符 (\0) 發送到 fd。 通常不會對字符串執行此操作, strlen(str) 可能是您想要的。

在第二:

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

文件名沒有被賦值,所以這兩個打開幾乎肯定會失敗。 當他們這樣做時,他們返回一個 NULL 指針,所以第一次嘗試使用它們:

而(!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;
}

所以你的主要看起來更像:

...
   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);
       }
   }
....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM