C 如何从fopen转换为open功能?
我似乎不知道如何从fopen转换为open。我没有太多的c语言经验,所以这对我来说是非常难以承受的 以下是它本身的情况: 在cache_reader.c文件中,只有打开和关闭功能: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
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}