C 文件操作

2021/5/22 10:29:28

本文主要是介绍C 文件操作,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 前言——文件是什么
  • 一、怎么打开和关闭文件?
    • 1.文件指针
    • 2.打开文件
      • 2.1文件打开模式
    • 3.关闭文件
  • 二、文本文件读写
    • 1.读
    • 2.写
  • 三、二进制文件的读写
    • 1.读
    • 2.写
  • 四、文件定位
    • 位置标志在哪儿
    • 位置标志移动到文件开头
    • 位置标志移动到任意位置
    • 文件缓冲区
  • 五、注意事项


前言——文件是什么

C语言里文件就是一种数据组织,根据所包含的数据形式的不同,分为ASCII码(文本)和二进制文件,两者区分在于存储的方式,文本文件中的字符是用ASCII码存储的,一个字节就是一个字符,没有int,double等类型。而二进制会根据int,bouble等类型分配不同的内存空间,比如int就是4个字节的。


一、怎么打开和关闭文件?

类似于脑经急转弯里怎么把大象装进冰箱的问题,如果不打开冰箱(打开文件),大象也是塞不进去的(文件内容也没法操作)。

1.文件指针

文件是一个数据组织,程序要完整的能操作它,就需要有它的各种信息,而不是单一的名字就够了。

C语言里给文件定义了一个结构体,用来存放一个文件的所有信息,类似于个人档案。

这个结构体名称:STRUCT_IO_FILE),有一个别名:FILE,可以直接使用,FILE结构体和对文件操作的库函数在 stdio.h 头文件中声明。

流程:
打开文件 -> fopen函数在内存创建一个FILE结构体对象,存储该文件信息 ->创建结构体成功后,返回给主程序这个FILE结构体的内存地址。完成打开文件的工作。
所以,文件指针的真实含义其实是FILE结构体在内存的地址,而不是文件在硬盘内的地址。

2.打开文件

打开途径:利用标准库里的fopen函数
形式:

FILE *fopen( const char *filename, const char *mode );
//返回值:FILE结构体指针
//第一个参数:文件名
//第二个参数:文件打开的模式(稍后再讲)

文件名:实际开发中,采用文件的全路径。如果不包含路径就表示程序运行的当前目录

2.1文件打开模式

就像参数可以是只读,可修改一样,为了让文件访问更加安全,文件的打开需要指定模式

模式简写含义
rread 只读 文件必须存在否则打开失败
wwrite 只写 文件若存在则清空内容从头开写 若不存在可以直接创建文件(别乱用,不然写好的文件内容直接清空了哭都来不及)
aappend 追加只写 w的追加版 文件若存在直接续写
r+r的可写版本 文件要求与r一样
w+w的可读版本 文件要求与w一样
a+a的可读版本 文件要求与a一样

3.关闭文件

关闭途径:利用fclose函数
形式:

void fclose(FILE *fp)
//处理的是FILE结构体

二、文本文件读写

1.读

途径:fgets,fgetc,fscanf函数,其中fgetc和fscanf没多少使用场景,主要介绍fgets
fgets功能:读取文件中的一行
形式:

char *fgets(char *buffer,size_t n,FILE *fp);
//返回值:一个字符串
//buffer:指望读取内容用的容器,存储文件的一行内容
//n:打算读取内容的长度,比如helloworld只想要hello
//fp:文件指针,后面类似内容就不再解释了

2.写

途径:fprintf是用的最多的,主要介绍它,其他的fputc、fputs了解下就行
fprintf功能:显而易见,输出内容到文件。
形式:

int fprintf(FILE *fp, const char *format, ...);
//返回值:如果成功,则返回写入的字符总数,否则返回一个负数。
//format:输入的字符串
//…:format中可能出现的格式符如%d所对应的对象

fprintf和fgets一个把文件指针参数放最左,一个放最右,真是不够专一

三、二进制文件的读写

二进制文件与文本文件的不同在于二进制文件没有字符串也没有行的概念,因此传给二进制文件的数据是以数据块的形式传递的。

1.读

途径:fread
形式:

szie_t fread (void *str,size_t size,size_t nmemb,FILE* stream);
//str:同文本文件的意义相同,只不过类型可以是结构体,数组等等
//size:这是要读取的每个元素的大小,以字节为单位,一般固定填1
//nmemb:打算读取的元素的数量

调用fread函数如果成功的读取到内容,函数返回读取到的内容的字节数,如果读取错误或文件已结束,返回空,即0。如果fread返回空,可以认为是文件结束而不是发生了错误,因为发生错误的情况极少出现。

2.写

途径:fwrite
形式:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
//ptr:要输入的数据的地址,可以是字符串,结构体,变量等
//size:这是要读取的每个元素的大小,以字节为单位,一般固定填1
//nmemb:打算写入数据的元素数

四、文件定位

文件内部有个位置标志,相当于编代码时的光标,用来指示目前文件读写的位置。

这个位置标志也有人叫位置指针,不过不是真的内存中的地址,仅仅是文件里的一个标志,我就直接叫位置标志。

文件每读写一次,位置标志就会移动一次,它不需要您在程序中定义和赋值,而是由系统自动设置,对程序员来说是隐藏的。

在实际开发中,偶尔需要移动位置标志,实现对指定位置数据的读写。我们把移动位置指针称为文件定位。

位置标志在哪儿

途径:ftell函数
形式:

long ftell(FILE *FP);
//返回值是当前位置标志相对于文件开头的字节数

位置标志移动到文件开头

途径:rewind函数
形式:

void rewind(FILE *FP);

位置标志移动到任意位置

途径:fseek函数
形式:

int fseek ( FILE *fp, long offset, int origin );
//offet:位置标志想移动的字节数,向后就是正数,向前就是负数
//origin:起始位置,0是文件开头,1是当前位置,2是末尾

当offset是向文件尾方向偏移的时候,无论偏移量是否超出文件尾,fseek都是返回0,当偏移量没有超出文件尾的时候,位置标志是指向正常的偏移地址的,当偏移量超出文件尾的时候,位置标志是指向文件尾的不会返回偏移出错-1值。

当offset是向文件头方向偏移的时候,如果offset没有超出文件头,是正常偏移,位置标志指向正确的偏移地址,fseek返回值为0,当offset超出文件头时,fseek返回出错-1值,位置标志还是处于原来的位置

文件缓冲区

在操作系统中,存在一个内存缓冲区,当调用fprintf、fwrite等函数往文件写入数据的时候,数据并不会立即写入磁盘文件,而是先写入缓冲区,等缓冲区的数据满了之后才写入文件。还有一种情况就是程序调用了fclose时也会把缓冲区的数据写入文件。

在实际开发中,如果程序员想把缓冲区的数据立即写入文件,可以调用fflush库函数,它的声明如下:

int fflush(FILE *fp);

函数的参数只有一个,即文件指针,返回0成功,其它失败,程序员一般不关心它的返回值。

五、注意事项

1 调用fopen打开文件的时候,一定要判断返回值,如果文件不存在、或没有权限、或磁盘空间满了,都有可能造成打开文件失败。

2 文件指针是调用fopen的时候,系统动态分配了内存空间,函数返回或程序退出之前,必须用fclose关闭文件指针,释放内存,否则后果严重。

3 如果文件指针是空指针或野指针,用fclose关闭它相当于操作空指针或野指针,后果严重。

4 一般来说,二进制文件有约定的数据格式,程序必须按约定的格式写入/读取数据,比如存写数组的二进制文件在读取时fread也必须用数组形式的变量形参。



这篇关于C 文件操作的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程