C语言——文件操作

C语言

  • 知识基础
  • 控制语句
  • 函数
  • 输入输出
  • 指针和数组
  • 用户自定义数据类型
  • 文件操作


结合《输入输出》理解文件流和缓存区的概念!

一、打开与关闭文件

1.文件指针

每个被使用的文件都会在内存中开辟一个文件信息区,存储与文件相关的信息,这些信息被存在一个结构体变量中,名为FILE结构体,我们想要进行文件操作实际上不会直接操作磁盘,而是通过库函数读入文件信息,让函数进行相应的操作实现我们的需求。
一般我们会定义一个指针指向打开的文件信息区,文件指针:FILE *fp,我们在输入输出中已经提到过标准输入输出的文件指针为stdin\stdout,我们可以简单的将文件指针看作文件流的等价物。

#ifndef _FILE_DEFINED
struct _iobuf {
    char *_ptr; //文件输入的下一个位置
    int _cnt; //当前缓冲区的相对位置
    char *_base; //指基础位置(即是文件的起始位置)
    int _flag; //文件标志
    int _file; //文件的有效性验证
    int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
    int _bufsiz; //
    char *_tmpfname; //临时文件名
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

综上,我们熟练掌握文件操作函数,就啥毛病没有。。。

2.打开文件

函数声明FILE *fopen(const char *filename, const char *mode)

输入:文件名(文件路径+文件主干+文件后缀),存储在数组中是有长度限制的;
访问模式参数,描述的是文件打开的方式,允许的操作等状态。

访问模式说明
r只读,可以向程序输入文件中的数据,如果文件不存在,报错
w只写,程序向文件写入数据,如果文件不存在,新建一个文件
a追加,程序从文件末尾写入数据,如果文件不存在,出错
r+/a+读写,文件不存在,报错
w+读写,文件不存在,新建文件
*b*打开二进制文件
返回值:返回一个文件指针,指向打开的文件流,所以必须要用一个文件指针变量接收返回值;如果出错,返回NULL,可以据此判断出错与否。
说明:主要掌握wra就行;a模式会保留文件末尾的文件结束符EOFa+模式则不会;规范化打开文件,判断成功与否;
FILE fp;
if((fp=fopen(filename, "r")) == NULL){//还有多种判断方式
	printf("cann't open %s\n", filename);
	exit(0);
}

函数声明FILE *freopen(const char *filename, const char *mode, FILE *stream)

输入:新文件名;访问模式;旧文件流指针,该指针对应一个已经打开的文件流;
返回值:关闭旧的文件流,依规定的访问方式打开文件名对应文件,返回新的文件指针;如果失败,返回NULL
说明:本函数可以用于重定向,比如改变标准输出至新的文件,输入的内容将写进指定文件而非显示器;

#include <stdio.h>
int main (){
   FILE *fp;
   printf("该文本重定向到 stdout\n");
   fp = freopen("file.txt", "w+", stdout);
   printf("该文本重定向到 file.txt\n");
   fclose(fp);
   return 0;
}

3.关闭文件和文件控制函数

函数原型int fclose(FILE *stream)

输入:文件指针,代表想要关闭的文件流。
返回值:整数,正常关闭返回零;出错返回EOF
说明:一个open对应一个close,这是基本操作;close会刷新缓冲区。

函数原型void clearerr(FILE *stream)

输入:文件指针,想要清空错误状态的文件流。
返回值:空。
说明:在发生错误的情况之后使用,例如,让open函数返回值不再是EOF

函数原型int feof(FILE *stream)

输入:文件指针,一个打开的文件流;
返回值:文件流状态是文件结束符EOF时,该函数返回一个非零值,否则返回零。
说明:文件到末尾的情况下(读到-1),状态被置EOF;需要注意当文件内部位置指针指向文件结束时,并未立即置位 FILE 结构中的文件结束标记,只有再执行一次读文件操作,才会置位结束标志,此后调用 feof 才会返回为真。

函数原型int ferror(FILE *stream)

输入:文件指针。
返回值:整数,标识文件流当前的状态,只要当前文件操作出错,函数返回非零数,如果无错,返回零。
说明:其作用是检查每一次文件流操作之后的错误状态,与feof不同,文件操作出错,立即置为1。

函数原型int fflush(FILE *stream)

输入:文件指针;
返回值:刷新缓冲区成功返回零;出错返回EOF
说明:在文件关闭时,缓冲区会自动刷新,但是在一个循环执行较久的程序中,最好在较小的操作后及时刷新缓冲区,从而及时得到结果,以便之后可能的使用。

二、读写函数

1.文件读写

函数原型size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

输入:ptr指向将要接受文件内容的内存空间的指针;size要读取的元素的大小,以字节为单位;nmemb表示要读取的元素的个数;最后的文件指针指明对象;
返回值:成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。
说明:能够读取多少内容,取决于size*nmemb

函数原型size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

输入:ptr指向将要写入文件的内容存储的内存空间的指针;…
返回值:…
说明:和fread使用方法是一致的!!!二者采用的是二进制读写的方式,效率是高于之后的格式化读写方式的;

函数原型int fprintf(FILE *stream, const char *format, ...)

输入:文件流;格式化标签和之前的标准输入输出是一致的;
返回值:如果成功,则返回写入的字符总数,否则返回一个负数。

2.格式化输入输出(字符输入输出)

  • int fprintf(FILE *stream, const char *format, …)
  • int sprintf(char *str, const char *format, …)
  • int fscanf(FILE *stream, const char *format, …)
  • int sscanf(const char *str, const char *format, …)
  • int fgetc(FILE *stream)
  • char *fgets(char *str, int n, FILE *stream)
  • int fputc(int char, FILE *stream)

说明:以上函数使用方式与到标准输入输出的用法大同小异,可以放心使用,其使用注意事项都是一致的。

三、文件定位

函数原型int fseek(FILE *stream, long int offset, int whence)

输入:文件流;这是相对 whence 的偏移量,以字节为单位;开始添加偏移 offset 的位置;

常量含义
SEEK_SET文件开头
SEEK_CUR当前位置
SEEK_END文件末尾

返回值:如果成功,则返回零,否则返回一个非零数。
说明:可以实现比较自由的定位;

函数原型void rewind(FILE *stream)

输入:文件流;
返回值:空;
说明:将指定文件流指回文件开头;


总结

文件是系统对磁盘数据的抽象,对文件的读写通过简单的函数调用就可以实现,我们要熟悉文件流的概念,掌握打开->操作->关闭三步走,熟悉读写函数的参数和作用保证万事大吉!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值