用 C 语言编写我自己的 Cat 函数

Vzq*_*van 5 c function cat eof fgetc

嗨,我不知道如何在 C 中模拟我自己的 Cat 函数,我知道当没有设置参数并且我已经得到它时它是如何工作的,但我的问题是当我尝试打开一个文件然后打印自身时......

到目前为止我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char* argv[])
{  
    char *a1 = (char*) malloc (sizeof(char));
    int sz, fd,cont=0, cont1=0;
    char *b1 = (char*) malloc (sizeof(char));
    //char *a2 = (char*) malloc (sizeof(char));
    char * a2;
    char *b2 = (char*) malloc (sizeof(char));

    // NO PARAMETERS
    while (argc == 1){      
        sz=read(0, a1, 1);
        b1[cont]=a1[0];

        if(b1[cont]=='\n'){
            write(1,b1,cont);
            write(1,"\n",1);
            b1=NULL;            
        }

        cont=cont+1;
        b1=(char*) realloc(b1, sizeof(char)*cont);
      }

    // 1 PARAMETER (FILE)   /*Here is the problem*/
    if (argc > 1){

        fd=open(argv[1],O_RDONLY);
        a2=fgetc(fd);

        while (a2 != EOF){
            b2[cont1]=a2;
            cont1=cont1+1;
            b2=(char*) realloc (b2, sizeof(char)*cont1+1);
            a2=fgetc(fd);
        }

        write(1,b2,cont);
        b2=NULL;
        close(fd);  
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我应该做些什么 ?

Jon*_*ler 4

如果您正在使用open()and close(),则不能使用fgetc(). 您需要使用fopen()并且fclose()能够使用fgetc()

无论哪种方式,您都需要一个可以使用标准输入(拼写为0stdin)或打开的文件(fdfp为“文件描述符”和“文件指针”的常规名称)调用的函数。您也可以指定输出流。因此,例如,接口:

int cat_fd(int ifd, int ofd);
int cat_fp(FILE *ifp, FILE *ofp);
Run Code Online (Sandbox Code Playgroud)

然后,您的主程序使用标准输入和标准输出或使用打开的文件和标准输出来调用您选择的函数。


此外,您还有:

char *a1 = (char*) malloc (sizeof(char));
Run Code Online (Sandbox Code Playgroud)

忽略演员阵容,这是一种昂贵的写作方式:

char a1[1];
Run Code Online (Sandbox Code Playgroud)

您的循环一次读取一个字符。这对于来自 的文件流来说没问题<stdio.h>,但如果您使用文件描述符,则对性能不利。您应该一次读取 4096 个字符的块。

int cat_fd(int ifd, int ofd)
{
    char buffer[4096];
    ssize_t nbytes;
    while ((nbytes = read(ifd, buffer, sizeof(buffer))) > 0)
    {
        if (write(ofd, buffer, nbytes) != nbytes)
            return -1;
    }
    return (nbytes < 0) ? -1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

您不需要动态内存分配;它只会让你感到困惑并在程序中浪费时间。函数中的代码main()看起来更像是:

if (argc == 1)
{
    if (cat_fd(0, 1) != 0)
        fprintf(stderr, "failed to copy standard input\n");
}
else
{
    for (int i = 1; i < argc; i++)
    {
        int fd = open(argv[i], O_RDONLY);
        if (fd < 0)
            fprintf(stderr, "failed to open %s for reading\n", argv[i]);
        else
        {
            if (cat_fd(fd, 1) != 0)
                fprintf(stderr, "failed to copy %d to standard output\n", argv[i]);
            close(fd);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

重写以供使用cat_fp()是对读者的一种练习。您可能会发现C 语言中经过验证且真实的简单文件复制代码相关。