c语言中关于文件操作的总结

1、含义:

存储在外存储器上,相较于常量、变量、数据等都是存储在内存储器上的。

键盘是输入文件stdin;

显示器是输出文件stdout;

写文件,我们理解为输出,从内存到外存;比如printf,fprintf,fputc,fputs,fwrite;

读文件,我们理解为输入,从外存到内存;比如scanf,fscanf,fgetc,fgets,fread;

2、分类:

1)按照存取方式:

顺序存取:读写操作总是从文件的开始位置开始;

随机存取:读写操作可以从文件的任意位置进行。

2)按照存取形式:

文本文件:每个字符都是以ASCII码值的形式存储;定长译码编码,但文件可识别。

二进制文件:把数据按其在内存中的存储形式(二进制码)形式存储;不定长译码编码,但文件不可识别。

例如:

3.14,文本文件,会将每个数字看做是字符存储的,一个字符占一个字节;//打开文件后,所见即所得;

若作为二进制文件存储的话,如果使用float类型,则是占4个字节,使用double则是占8个字节。//打开文件后,是乱码;

但如果文本文件和二进制文件都存储的是字符数组的内容的话,打开二进制文件,看到的是对应的十六进制数。

3、文件指针

#include <stdio.h>

typedef struct{
    short level; //缓冲区满或空 程度
    unsigned flags;//文件状态标志
    char fd; //文件描述符
    unsigned char hold;// 如无缓冲区不读取字符
    char filename[20];//文件名
    char path[30];//文件路径
}FILE;

 FILE* fp;

4、打开文件

对文件进行读写操作前,需要打开文件:

FILE* fp = fopen(文件名,文件的打开方式);

例如:
FILE* fp = fopen("test.txt","r");
FILE* fp = fopen("\\nand_flash\\test.txt","r");\\用两个/表示一个\

若文件无法打开,会返回NULL。
故:
FILE* fp;
if((fp = fopen("test.txt","r"))==NULL)
{
    printf("fopen file fail\n");
    exit;
}
打开方式 含义 打开方式 含义
“r” 只读,打开文本文件,文件必须存在 “r+” 可读写,打开文本文件,文件必须存在
“w” 只写,打开文本文件,文件不必存在,若存在,fopen的时候内容会被清除 “w+” 可读写,建立并打开新的文本文件,文件可以不存在,如果存在,fopen的时候内容会被清除
“a” 追加写,文件可以不存在,从文本文件尾开始添加 “a+” 可读写,打开文本文件,文件可以不存在,在文件末尾添加
"rb" 只读,打开二进制文件,文件必须存在 "rb+" 读写,打开二进制文件,文件必须存在
“wb” 只写,打开二进制文件,文件不必存在,若存在,内容会被清除 “wb+” 读写,建立并打开新的二进制文件,文件可以不存在,如果存在,内容会被清除
"ab" 追加,文件可以不存在,从二进制文件尾开始添加 "ab+" 读写,打开二进制文件,文件可以不存在,在文件末尾添加

r与r+比较:二者都需要先建立文件;r+增加了可写的功能,即:打开一次文件,可以写文件,读文件;写的时候是在文件位置指针的位置写的,会覆盖指针后面的内容。写几个字节覆盖几个字节。

      r+的写优势:1)不会清除原文件的所有内容,通过fseek()函数来改变文件位置指针来写内容(写几个,覆盖几个)。2)读写文件时,只需要打开一次文件即可。

w与w+比较:二者对文件的存在都没有要求,如果文件存在,fopen的时候,原文件被删除,重新创立了新的文件;w+增加了读功能,即:写入文件后,通过fseek来更改文件位置指针,还可以将文件的内容读出来,

      注意,w+是无法先读后写,因为,使用fopen后,就是一个空的文件。

r与w的比较:r文件必须要存在;w文件可存在,可不存在,如果存在,原文件中的内容会被覆盖(fopen的时候,原文件被删除,重新生成了一个同名的文件),如果不存在,会建立这个文件。

      w的优势,重新生成一个新的文件,并且会覆盖原文件。

r+与w+的比较:二者都既能读又能写;r+要求文件存在,w+不要求文件存在,若存在,则会删除重新创建新的文件(即使用w+属性,无论文件存不存在,都会重新创建);

r+可以先写后读,也可以先读后写(因为文件已存在,且其中有内容),w+只能先写后读,因为fopen之后,文件为新建的文件为空,故只能先写后读。

w与a的比较:二者都不要求文件是否存在;w无论文件存在与否,都会删除文件,新建文件;a的话,如果文件未创建的话,与w一样,如果文件创建的话,则会在文件末尾续写内容。

a与a+的比较:二者都不要求文件是否存在,都不能改变文件的原内容;a只能在末尾添加,文件位置指针无效(即fseek无效);a+只能在结尾追加写, 文件位置指针只对读有效 (写操作会将文件指针移动到文件尾)

5、关闭文件 

对文件读写完成后,应该关闭,防止丢失数据;

关闭文件的实质,是释放文件指针,使文件指针变量不再指向该文件。

fclose(fp);
//关闭成功返回0;
//关闭失败返回非0

6、文件的读写

6.1 fscanf 和fprintf //读写文本文件,数据格式任意

记忆:fscanf与fprintf 与scanf 和printf的格式及含义基本上是相同的;

scanf,是键盘(stdin文件)读取一个值,并赋值给一个变量;//fscanf也是从文件中读取值,赋给某个变量

   scanf("%d",&m)等价于 fscanf(stdin,"%d",&m);

printf,是将一个变量的值,写入到显示器(stdout文件);//fprintf也是将某个变量写到文件中;

   printf("%d",n);等价于 fprintf(stdout,"%d",n);

1)fprintf(文件指针,格式字符串,输出项表)
例如:
fprintf(fp,"%d",m);//将变量m以%d的形式写到fp指向的文件中

2)fscanf(文件指针,格式字符串,输入项表)
例如:
fscanf(fp,"%d",&n);//注意取地址符号&//将fp所指的文件以%d的形式读取到变量n中

6.2 fputc(putc)和fgetc(getc)//从文本文件中读写字符

fputc(ch,fp);//ch可以是字符常量,可以是字符变量,写入到fp所指的文件中
putchar(ch);等价于fputc(ch,stdout);

ch = fgetc(fp);//从fp所指的文件中读取字符作为返回值赋给字符型变量ch
ch = getchar();等价于ch = getc(stdin);

6.3 fputs和fgets函数// 从文本文件中读写字符

fputs(str,fp);//str是待写入文件的字符串的首地址
//注意:字符串最后的\0不会写入文件,也不会自动加'\n';
写入成功,函数值为非0,否则为0;

fgets(str,n,fp);//str是存放字符串的起始地址;n是int型变量
//从fp所指的文件中读n-1个字符依次放入到以str为旗帜地址的内存中,读入结束后,自动在最后加'\n',并以str作为函数值返回。
//注意:调用该函数时,最多只能读取n-1个字符。要为'\0'保留一个字符的空间

 6.4 fwrite和fread//二进制文件中读写数据

fwrite(buffer,size,count,fp);
//buffer为指针,代表内存中一段存储空间的首地址;
size,代表每单元的字节数;
count代表要进行读写的单元数
//将以buffer为其实地址的内存中的count个单元,每个单元size个字节写到fp所指的文件中。

int a[4]={1,2,3,4}; fwrite(a,2,4,fp);
//将以a为起始地址的内存中的4个单元,每单元2个字节写(输出)到fp所指的文件中。

fread(buffer,size,count,fp);
//buffer是指针,代表内存中存储空间的地址;
count代表进行读写的单元数;
size带包每单元的字节数;
//从fp所指的文件中读(输入)count个单元,每个单元size个字节,到以buffer为起始地址的内存中。

int  a[4];
fread(a,2,4,fp);
//从fp所指的we年中读4个单元,每个单元2个字节,到以a为起始地址的内存中。

7、判断文件是否结束

1)feof(fp); 判断文件是否结束------ f  end of file//可以判断二进制文件,也可以判断文本文件

文件结束:返回值为1;

文件没有结束,返回值为0;

2)EOF;//文本文件

因为文本文件都是ASCII码,0-255,不可能为-1,所以使用EOF作为文本文件的结束标志。

8、文件定位函数

文件fopen后,文件位置指针指向文件的开头,第一个数据之前;//注意是文件位置指针,不是文件指针

文件fclose后,文件位置指针指向文件末尾,最后一个数据之后。

对数据进行读操作后,文件位置指针指向尚未读数据之前,即是从指针后的数据开始读。

当数据进行写操作后,文件位置真值指向刚写入数据之后。

我们使用fseek函数实现改变文件的位置指针。

起始点 名称 代表数字
文件开始位置 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾位置 SEEK_END 2
fseek(fp,offset,origin);//一般用于二进制文件
offset是以origin为基点,以字节为单位的位移量,当offset为正整数,表示位置指针从指定位置向后移动,当offset为负整数,表示位置指针从指定位置向前移动,为长整型。

fseek(fp,30L,SEEK_SET);//位置指针从开始位置向后移30个字节。
fseek(fp,-10*sizeof(int),SEEK_END);//位置指针从文件尾部位置向前移10*sizeof(int)个字节。

fseek(fp,0L,SEEK_SET);//位置指针移动到开始位置。
fseek(fp,0L,SEEK_END);//位置指针移动到末尾位置。
long t = ftell(fp);
//返回当前位置指针据文件开头的字节数

//该函数可以用来获取文件的大小
fseek(fp,0L,SEEK_END);
long t = ftell(fp);
rewind(fp);//无返回值
//使文件位置指针返回到文件开头位置,等价于 fseek(fp,0L,SEEK_SET);

9、总结

1)c语言中关于文件的操作都是以f开头的。

2)r+,w+,a+,其实都可以通过r,w,a及fseek函数多次操作实现。

猜你喜欢

转载自blog.csdn.net/modi000/article/details/113096605