1什么是文件
磁盘上的文件就是文件
文件分两种:
程序文件:
- 包括源程序文件(.c)、目标文件(.obj)、可执行程序(.exe)
数据文件:
- 文件的内容不一定是程序,而是程序运行时读写的数据。比如程序运行时需要从中读取数据的文件,或者输出内容的文件。
(此前数据的输入输出都是以终端为对象,键盘输入,显示屏输出。其实有时我们会把信息输出到磁盘上,当需要的时候再在磁盘上读取到内存中使用。)
2文件名
文件要有一个唯一的文件标识,以便用户识别使用。
文件名包含3个部分:文件路径+文件名主干+文件后缀
为了方便文件标识常称为文件名。
3文件类型
根据数据的组织形式,分为:
- 文本文件或者二进制文件
二进制文件:以二进制的形式存储,不加以转换
文本文件:转换后以ascll码形式存储
字符以ascll码形式存储。数值型则可以ascll码或二进制。
如:
10000的存储-->ascll码:10000(5个字节);二进制形式:00 00 27 10(4个字节)
4文件缓冲区
缓冲文件系统:系统自动在内存中为程序中每一个正在使用的文件开辟一块文件缓存区。
内存向磁盘输出数据和磁盘向内存的输入数据都会先送到缓冲区,直到装满或结束。缓存区大小由c编译系统决定。
5文件指针
缓存文件系统中,关键概念是文件类型指针。即文件指针。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,存放文件的相关信息(文件名,文件状态,即文件当前位置),保存在一个结构体变量中。结构体类型是有系统声明的取名FILE。
//创建一个FILE*的指针变量
FILE* pf;//文件指针变量
可以使pf指向某个文件的文件信息区(结构体变量)==》通过文件指针变量能够找到与它相关联的文件。
6文件的打开与关闭
(1)
- 读之前打开,使用之后关闭文件。
- 在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,相当于创建了指针与文件的关系。
(2) fopen()函数打开文件;fclose()来关闭文件。
//格式
FILE* fopen(const char* filemane, const char* mode);
int fclose(FILE* stream);
(3)打开方式(部分):
文件使用方式 | 含义 | 如果文件不存在 |
r 只读 | 为输入数据,打开已存的文本文件 | 出错 |
w 只写 | 为输出数据,打开一个文本文件 | 建立新的 |
a 追加 | 向文件尾部添加文件 | 出错 |
rb 只读 | 为输入数据,打开一个二进制文件 | 出错 |
wb 只写 | 为输出数据,打开一个二进制文件 | 建立新的 |
ab 追加 | 向二进制文件追加数据 | 出错 |
r+ 读写 | 为读和写,打开一个文本文件 | 出错 |
w+ 读写 | 为读和写,建立一个新的文件 | 建立新的 |
a+ 读写 | 打开一个文件,在尾部进行读写 | 建立新的 |
rb+ 读写 | 为了读和写,新建一个新的二进制文件 | 建立新的 |
... | ... | ... |
(4) fopen()::取文件名方式:
相对路径:
- text.txt 在当前目录
- ..\\text.txt 在上一个目录
绝对路径
- 把从什么盘开始到文件全部写出来
7文件的顺序读写
(1)
功能 | 函数名 | 适用于 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所以输出流 |
文本行输入函数 | fgets | 所以输入流 |
文本行输出函数 | fputs | 所以输出流 |
格式化输入函数 | fscanf | 所以输入流 |
格式化输出函数 | fprintf | 所以输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
输入到程序,输出到程序外。
①
- int fputs(const char *string,FILE* stream);
- char *fgets(char* string , int n,FILE* stream);
②
- int printf(const char*format[,argument]...);
- int fprintf(FILE* stream,const char*format[,argument]...)
③
- int scanf(const char*format[,argument]...);
- int fscanf(FILE* stream,const char*format[,argument]...);
④
- size_t fwrite(const void*buffer,size_t size,size_t count,FILE*stream) ;
- size_t fread(void*buffer,size_t size,size_t count,FILE*stream) ;
(2)
标准输入:键盘输入,stdin FILE*
标准输出:屏幕输出,stdout FILE*
int main() {
int ch = fgetc(stdin);
fputc(ch, stdout);
return 0;
}
(3)
//写文件 w模式下
//1
fputc('h', pf);
//2
fputs("hello",pf);
(4)
//读文件 r模式下
//1
int ch=fgetc(pf);
printf("%c", ch);
//2
char buf[1024]={0};
//中间创建FILE* pf
fgets(buf,1024,pf);//会读取\n
printf("%s\n",buf);
//与gets()和puts()相理解
8文件的随机读写
(1)
fseek
根据文件指针的位置和偏移量来定位文件指针
int fseek(FILE * stream,long int offset,int origin);
- offset为求偏移量,origin为文件指针的位置。
- SEEK_CUR文件指针的当前位置,SEEK_END文件指针的末尾位置,SEEK_SET文件指针的起始位置
(2)
ftell
返回文件指针相对于起始位置的偏移量
long int ftell(FILE* stream);
(3)
rewind
让文件指针的位置回到文件的起始位置
void rewind(FILE* stream);
9文件结束的判定
(1)
被错误使用的feof
(在文件读取过程中,不能用feof函数的返回值直接用来判断文件是否结束。而是应用于当前文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束)
(2)
①文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgetc)
②二进制文件读取是否结束,判断返回值是否小于实际要读的个数(fread)
10其他(例)
(1)
#include<stdio.h>
#include<errno.h>
int main() {
FILE* pf = fopen("text.txt", "w");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
//打开文件
//写文件
fputc('h', pf);
//关闭文件
fclose(pf);
pf = NULL;
}
结果:
会在当前目录新建一个内容为h的text.txt的文件。(若text.txt换成..\\text.txt:结果则是上一个目录)。
(2)
对比:
- scanf/fscanf/sscanf
- printf/fprintf/sprintf
第一列:针对标准输入输出流,格式化输入输出语句
第二列:针对所以输入输出流,格式化输入输出语句
第三列:sscanf是从字符串中读取格式化数据;sprintf是把格式化数据输出(存储)字符串
- int sscanf(const char*buffer,const char*format[,argument]...);
- int sprintf(char *buffer,const char*format[,argument]...);
11 最后
慢慢补充吧,多实践,(员工簿?)