Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何从fopen转换为open功能?_C_File - Fatal编程技术网

C 如何从fopen转换为open功能?

C 如何从fopen转换为open功能?,c,file,C,File,我似乎不知道如何从fopen转换为open。我没有太多的c语言经验,所以这对我来说是非常难以承受的 以下是它本身的情况: 在cache_reader.c文件中,只有打开和关闭功能: void cr_close(cr_file* f){ free(f->buffer); fclose(f->file); } cr_file* cr_open(char * filename, int buffersize) { FILE* f; if ((f = fopen(filen

我似乎不知道如何从fopen转换为open。我没有太多的c语言经验,所以这对我来说是非常难以承受的

以下是它本身的情况:

在cache_reader.c文件中,只有打开和关闭功能:

void cr_close(cr_file* f){
free(f->buffer);
fclose(f->file);
}

cr_file* cr_open(char * filename, int buffersize)
{
    FILE* f;
    if ((f = fopen(filename, "r")) == NULL){
         fprintf(stderr, "Cannot open %s\n", filename);
         return 0; }

    cr_file* a=(cr_file*)malloc(sizeof(cr_file));
    a->file=f;
    a->bufferlength=buffersize;
    a->usedbuffer=buffersize;
    a->buffer=(char*)malloc(sizeof(char)*buffersize);
    refill(a);
    return a;
 }
在cache_reader.h文件中:

typedef struct{
   FILE* file;        //File being read
   int bufferlength;  //Fixed buffer length
   int usedbuffer;    //Current point in the buffer
   char* buffer;      //A pointer to a piece of memory
                 //  same length as "bufferlength"
 } cr_file;
 //Open a file with a given size of buffer to cache with
 cr_file* cr_open(char* filename, int buffersize);
 //Close an open file
 void cr_close(cr_file* f);
 int refill(cr_file* buff);
在cache_example.c文件中:

int main(){
char c;

 //Open a file
 cr_file* f = cr_open("text",20);  

 //While there are useful bytes coming from it
 while((c=cr_read_byte(f))!=EOF)
 //Print them
 printf("%c",c);

 //Then close the file
 cr_close(f);

//And finish
return 0;
}
我知道我需要将fclose更改为close,fopen更改为open。但我不懂其他的大部分东西。我每件事都会犯很多错误,我不确定指针是如何解决的,因为我几乎没有任何使用指针的经验。我试图使用int-filenoFILE*stream,先说int-fd=filenoFILE*f,然后说fd=fopenfilename,r==NULL。这不起作用,我能找到的所有打开函数示例都只使用文件名,而不是字符指针来指定文件名。。。我以为只要将fclose更改为close就可以实现cr_close功能,但这也不起作用。我不确定是否也需要编辑cache_example.c文件


有人能帮我找到正确的方法吗?

以下建议代码:

干净地编译 消除不需要/未使用的代码 包括include语句以及需要它们的原因 执行所需的功能 使用每个OPs请求文件描述符,而不是文件指针 现在,拟议的守则

// following struct not actually used in this code
#if 0
typedef struct
{
   int fd;               // file descriptor number of input file
   /*
    * int bufferlength;  // Fixed buffer length
    * int usedbuffer;    // Current point in the buffer
    * char* buffer;      // A pointer to a piece of memory
    *                    // same length as "bufferlength"
    * */
} cr_file;
#endif
-------------------------

// following 3 header files for 'open()' and 'O_RDONLY'
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

// following for 'read()' and 'close()'
#include <unistd.h>

// following for 'exit()' and 'EXIT_FAILURE'
#include <stdlib.h>

// following for 'printf()', 'perror()'
#include <stdio.h>

int main( void )
{
    //Open a file
    int fd = open("text", O_RDONLY);
    if( 0 > fd )
    { // then open failed
        perror( "open for input file failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, open successful

    //While there are useful bytes coming from it
    char buf;

    while( read( fd, &buf, 1 ) > 0 ) 
    {
        printf( "%c", buf );
    }

    //Then close the file
    close( fd );

    //And finish
    return 0;
}
根据评论


本练习的目的是保持示例代码不变,但是 重新实现其他代码以使用文件描述符而不是文件描述符 溪流。 遗憾的是,标题不必要地暴露了结构的内部, 所以这个例子需要重新编译。 您将文件*成员更改为int。 您不会使用任何接受文件流参数的函数

标头cache_reader.h应包含此内容,而不是结构 定义:

typedef struct cr_file cr_file;
源缓存_reader.c应包含:

struct cr_file
{
    int file;
    int bufferlength;
    int usedbuffer;
    char *buffer;
};
这在客户端示例代码中为您提供了一个不透明类型,并允许 您可以在不需要重新编译客户端代码的情况下更改结构 当然,尽管您必须重新编译实现-我们 不能创造完全的奇迹

当然,您可以让您的客户机在任何时候重新编译代码 对库的内部进行更改。 然而,从长远来看,如果你能 对库代码的更改和改进,而无需 消费者要求其他程序员重新编译他们的代码。 二进制兼容性对于大型库(如 给定平台上的标准C库。 对于这样一个小项目,这并不重要,但你需要这样做 如果你愿意的话,至少在适当的时候了解更大规模的问题 坚持以编程为职业

返工代码 请注意,我的结论是我需要一些不同的成员来支持你的建议 用例-我需要知道分配的缓冲区的大小 缓冲区中实际的数据量,以及 阅读 我将成员重命名为bufmax your bufferlength,bufpos your 使用Buffer,并添加buflen

我为cr_read_byte编写了示例代码,它可以读取文件

然而,在支持写作方面也有大量工作要做, 在文件中移动,而不是一次移动一个字节,依此类推

cache_reader.h cache_reader.c 生成文件 除了我的堆栈中GitHub上的答案中显示的骨架makefile之外,您可以找到这段代码 将问题存储库作为文件溢出到
子目录。

您认为文件名和指向char的指针之间有什么区别?本练习的目的是保持示例代码不变,但重新实现其他代码以使用文件描述符而不是文件流。遗憾的是,头部不必要地暴露了结构的内部,因此需要重新编译该示例。您将文件*成员更改为int。您不会使用任何接受文件流参数的函数。如何将文件*更改为int。。?我认为fileno函数将完成我试图完成的任务。我还尝试将fprintf更改为printf,将stderr更改为stdout以使其正常工作。注意:更改字符c->int c以避免不正确的行为。相关:这是你能给Leffler教授的最完整的一课。@DavidC.Rankin:谢谢。我觉得另一个答案并没有真正起到多大的作用,尽管有一些危险,这是走得太远了。我还没有指出代码中的所有微妙之处,但这可能会有压倒OP的危险。我一直很欣赏那些布局合理的例子,我每次都学到了一些东西——这是一个好日子。我怀疑我是否能够充分欣赏这些小东西,因为我目前的编程水平,但是我已经能够通过查看这一个来相应地转换我的代码,从而得到我想要的。谢谢你的时间。谢谢你的例子。它很容易理解。
#ifndef CACHE_READER_H_INCLUDED
#define CACHE_READER_H_INCLUDED

typedef struct cr_file cr_file;

extern cr_file *cr_open(char *filename, int buffersize);
extern void cr_close(cr_file *f);
extern int cr_read_byte(cr_file *f);

#endif /* CACHE_READER_H_INCLUDED */
#include "cache_reader.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct cr_file
{
    int   file;     // File being read
    int   bufmax;   // Fixed buffer length
    int   bufpos;   // Current point in the buffer
    int   buflen;   // Amount of data in the buffer
    char *buffer;   // A pointer to a piece of memory
};

static void cr_refill(cr_file *f)
{
    if (f->bufpos >= f->buflen)
    {
        int nbytes = read(f->file, f->buffer, f->bufmax);
        if (nbytes > 0)
        {
            f->buflen = nbytes;
            f->bufpos = 0;
        }
    }
}

void cr_close(cr_file *f)
{
    free(f->buffer);
    close(f->file);
    free(f);
}

cr_file *cr_open(char *filename, int buffersize)
{
    int fd;
    if ((fd = open(filename, O_RDWR)) < 0)
    {
        fprintf(stderr, "cannot open %s for reading and writing (%d: %s)\n",
                filename, errno, strerror(errno));
        return 0;
    }

    cr_file *a = (cr_file *)malloc(sizeof(cr_file));
    char *b = (char *)malloc(sizeof(char) * buffersize);
    if (a == 0 || b == 0)
    {
        free(a);
        free(b);
        close(fd);
        fprintf(stderr, "cannot allocate %zu bytes of memory (%d: %s)\n",
                sizeof(cr_file) + buffersize, errno, strerror(errno));
        return 0;
    }
    a->file = fd;
    a->bufmax = buffersize;
    a->bufpos = 0;
    a->buflen = 0;
    a->buffer = b;
    return a;
}

int cr_read_byte(cr_file *f)
{
    if (f->bufpos >= f->buflen)
        cr_refill(f);
    if (f->bufpos >= f->buflen)
        return EOF;
    return f->buffer[f->bufpos++];
}
#include "cache_reader.h"
#include <stdio.h>

int main(void)
{
    cr_file *f = cr_open("text", 20);
    if (f != 0)
    {
        int c;
        while ((c = cr_read_byte(f)) != EOF)
            putchar(c);
        cr_close(f);
    }
    return 0;
}
CFLAGS  = -std=c11 -O3 -g -Wall -Wextra
LDFLAGS =
LDLIBS  =

FILES.c = cache_example.c cache_reader.c
FILES.o = ${FILES.c:.c=.o}
FILES.h = cache_reader.h

PROG1 = cache_example

PROGRAMS = ${PROG1}

all: ${PROGRAMS}

${PROG1}: ${FILES.o}
    ${CC} -o $@ ${CFLAGS} ${FILES.o} ${LDFLAGS} ${LDLIBS}

${FILES.o}: ${FILES.h}