文件操作
1. 什么是文件
存在磁盘上的文件是文件
在程序设计中,文件分为:程序文件,数据文件
程序文件
包括源程序文件(.c),目标文件(.obj),可执行程序(.exe)
数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件
2. 文件名
一个文件要有一个唯一的文件标识
文件名包含3个部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
3.文件类型
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
4.文件指针
FILE* pf;//文件指针变量
通过文件指针变量能够找到与它关联的文件
5.文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。
打开方式如下:
FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本文件尾添加数据 | 出错 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
“wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
6.文件操作函数
功能 | 函数名 | 适用于 |
---|---|---|
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
- fgetc
int fgetc(FILE *stream);
函数说明:fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。
返回值:getc()会返回读取到的字符,若返回EOF,则表示到了文件尾。
- fputc
int fputc(int c, FILE *stream);
函数说明:fputc会将参数c转为unsigned char后写入参数stream指定的文件中。
返回值:fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
- fgets
char* fgets(char * s, int n,FILE *stream);
s: 字符型指针,指向存储读入数据的缓冲区的地址
n: 从流中读入n-1个字符
stream:指向读取的流
- fputs
int fputs(const char *s, FILE *stream);
函数说明:fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。
返回值:若成功,则返回写出的字符个数,返回EOF则表示有错误发生。
- fscanf
int fscanf(FILE * stream,const char * format,...);
函数说明:从流中读取数据并根据参数格式将它们存储到附加参数指向的位置
返回值:成功时,该函数返回成功填充的参数列表的项数。由于匹配失败,
读取错误或文件结束的范围,此计数可以匹配预期的项目数或更少(甚至为零)。
如果在读取时发生读取错误或达到文件结尾,则设置正确的指示符(feof或ferror)。
并且,如果在成功读取任何数据之前发生任何一次,则返回EOF。
- fprintf
int fprintf(FILE * stream,const char * format,...);
函数说明:将格式化数据写入流,
通过写入所指的C字符串格式的数据流。如果格式包括格式说明(开头子序列%),
按照附加的参数格式被格式化,并将所得串置换它们各自的说明符中插入。
返回值:成功时,返回写入的字符总数。
如果发生写入错误,则设置错误指示符(ferror)并返回负数。
如果在写入宽字符时发生多字节字符编码错误,则将errno设置为EILSEQ并返回负数。
- fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
buffer 是读取的数据存放的内存的指针(可以是数组,也可以是新开辟的空间,buffer就是一个索引)
size 是每次读取的字节数
count 是读取次数
strean 是要读取的文件的指针
- fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);。
FILE* fa = fopen("F:/list.dat","a+"); //追加式写入
const char* j = "hello world";
fwrite(j,5,1,fa);
7.文件的随机读写
- fseek
根据文件指针的位置和偏移量来定位文件指针。
int fseek ( FILE * stream, long int offset, int origin );
- ftell
返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
- rewind
让文件指针的位置回到文件的起始位址
void rewind ( FILE * stream );
8.文件结束判定
被错误使用的 feof !!!
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
- 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)
例如:
fgetc判断是否为EOF.
fgets判断返回值是否为NULL. - 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。