FILE
简介:
文件用来存放程序、文档、音频、视频、片等数据的。文件就是存放在磁盘上的,一些数据的集合。在windows下可以通过写字板或记事本打开文本文件对文件进行编辑保存。写字板和记事本是微软程序员写的程序,对文件进行打开、显示、读写、关闭。作为一个程序员,必须掌握编程实现创建、写入、读取文件等操作对文件的操作是经常要用到的知识,比如:写飞秋软件传送文件等
文本文件与二进制文件
文本文件基于字符编码,常见编码有 ASCII、UNICODE 等一般可以使用文本编辑器直接打开
例如:数 5678 的以 ASCII 存储形式为:
ASCII 码:00110101 00110110 00110111 00111000歌词文件(lrc):文本文件
二进制码文件:基于值编码,自己根据具体应用,指定某个值是什么意思把内存中的数据按其在内存中的存储形式原样输出到磁盘上一般需要自己判断或使用特定软件分析数据格式
例如:数 5678 的存储形式为:
二进制码:00010110 00101110音频文件(mp3):二进制文件
图片文件(bmp)文件,一个像素点由两个字节来描述*****######&&&&&*代表红色的值#代表绿色的值&代表蓝色的值
二进制文件以位来表示一个意思。文本文件、二进制文件对比:
译码:文本文件编码基于字符定长,译码容易些;二进制文件编码是变长的,译码难一些(不同的二进制文件格式,有不同的译码方式)。
空间利用率:二进制文件用一个比特来代表一个意思(位操作);而文本文件任何一个意思至少是一个字符。二进制文件,空间利用率高。
可读性:文本文件用通用的记事本工具就几乎可以浏览所有文本文件二进制文件需要一个具体的文件解码器,比如读 BMP 文件,必须用读图软件
磁盘文件与设备文件
磁盘文件
指一组相关数据的有序集合,通常 存储在外部介质(如磁盘)上,使用时才调入内存.
如,我们在计算机上见到的文本文档,图片,视频,音频,等文件
设备文件
在操作系统中把每一个与主机相连的输入、输出设备看着是一个文件,把他们的输入、输出等同于对磁盘文件的读和写 键盘:标准输入文件,stdin屏幕:标准输出文件,stdout其他设备:打印机,触摸屏,摄像头,音响等
在Linux操作系统中,每一个外部设备都在/dev目录下有对应的一个设备文件,我们程序中想要操作设备,就必须对其所对应的文件进行操作stdin: 标准输入 默认为当前终端(键盘)
我们使用的 scanf、getchar 函数默认从此终端获得数据stdout:标准输出 默认为当前终端(屏幕)
我们使用的 printf、puts 函数默认输出信息到此终端stderr:标准错误输出设备文件 默认为当前终端(屏幕)
当我们程序出错使用:perror 函数时信息打印在此终端
标准 io 库函数对磁盘文件的读写特点
文件缓冲区
缓冲区的目的:提高磁盘使用效率。
刷新缓冲区的情况
1, 行刷新
2, 满刷新
3, 强制刷新
4, 关闭刷新
行刷新
缓冲区
触发行刷新
满刷新
强制刷新
关闭刷新
无刷新
:无缓冲区概念 写数据就立马进入文件 读数据立马进入内存
在读写文件的时候通过系统调用io(read write)对文件进行读写数据这个时候是无缓冲的,即写数据会立马进入文件,读数据会立马进入内存
概述: 系统提供的用于描述文件的结构体
typedef struct {short level; //缓冲区“满”或“空”的程度unsigned flags; //文件状态标志char fd; //文件描述符unsigned charhold; //如无缓冲区不读取字符short bsize; //缓冲区的大小unsigned char *buffer; //数据缓冲区的位置unsigned ar*curp; //指针,当前的指向unsigned istemp; //临时文件,指示器shorttoken; //用于有效性检查 }FILE; //在缓冲文件系统中,每个被使用的文件都要在内存中开辟一块 //FILE 类型的区域,存放与操作文件相关的信息
注意
> FILE是用来描述文件的结构体 > FILE *就可以指向一个文件 > FILE *被称为文件指针
文件操作函数
1 fopen
作用: 打开文件
语法:
#include <stdio.h>
FILE *fopen(const char *path, const char *mode); // 参数1 文件路径 相对绝对都行 参数2 对文件操作的选择 r w a
参数:path:打开的文件地址相对路径绝对路径mode:打开的模式:r:只读特点:文件不存在返回NULL,文件存在返回文件指针w:只写特点:文件不存在,创建文件.文件存在清空文件原内容,在打开,文件打不开(如:只读文件),返回NULLa:追加特点:文件不存在,创建文件.文件存在原文件末尾操作 +: 同时以读写打开指定文件分类:r+: 以可读、可写的方式打开文件(不创建新文件)w+: 以可读、可写的方式打开文件(文件不存在,创建文件,文件存在清空原内容,打开)a+:以添加方式打开文件,打开文件并在末尾更改文件(如果文件不存在,则创建文件)b:二进制文件
t:文本文件
rb:二进制文件只读
wb:二进制文件只写
ab:二进制文件追加 返回值: 打开的文件的文件指针
示例:
FILE *file = fopen("./test.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}
2 fclose
作用: 关闭文件
语法:
#include <stdio.h> int fclose(FILE *stream); 参数:fp:要关闭的文件指针 返回值:0:关闭成功非0:关闭失败
3 fgetc
作用
一次读取一个字符
语法:
所属头:stdio.h
函数:int fgetc(FILE *stream);
参数:读取的文件指针
返回值:读取到的字符
注意:以t的方式:读到文件结尾返回EOF,EOF是在stdio.h文件中定义的符号常量,值为-1以b的方式:读到文件结尾,使用 feof(后面会讲)判断结尾
4 fputc
作用:写入一个字符
语法
函数头:stdio.h
函数:int fputc(int c, FILE *stream)
参数:c:写入的数据stream:写入的文件指针
返回值:如果输出成功,则返回输出的字节值;如果输出失败,则返回一个EOF。
5 fgets
作用
# 一次读取一个字符串 只要不出现 \n 就是一个字符串 因为在一行
语法
函数头: stdio.h
函数: char *fgets(char *s,int size,FILE *stream); 示例:
参数:s:存储读取到的字符串的变量size:这是要读取的最大字符数(包括最后的空字符)。通常是使用以str传递的数组长度stream:读取的文件指针
返回值:成功返回 读取的字符失败返回 NULL
注意:读取到换行或文件结束
#include <stdio.h>
int main(int argc, char const *argv[])
{char arr[40];fgets(arr,40,stdin); // 从标准输入读取字符串到 arr 中for (int i = 0; i < 40; i++){printf("%c",arr[i]); }return 0;
}
6 fputs
作用 一次写入一个字符串
语法
函数头:stdio.h
函数:int fputs(const char *s, FILE *stream);
参数:s:写入的字符串stream:写入的文件指针
返回值:成功返回写入的字节数失败返回-1
7 fread 【**】
作用:一次读取n块
语法:
函数头stdio.h
函数size_t fwrite(viod *ptr,size_t size,size_t nmemb,FILE *stream)
参数:ptr:指向带有最小尺寸的size*nmemb字节的内存块的指针size:读取的每个元素的大小,单位字节nmemb:读取的元素个数stream:读取的文件指针
返回值:实际读到的块数
示例:
char *info = (char *)calloc(1, len); //动态开辟内存 分配的内存大小为 len 个字节
fread(info, len, n, file);参数1 表示动态开辟用来存储读取数据的内存参数2 表示每个数据块的大小(以字节为单位)参数3 n 表示要读取的数据块数量。参数4 表示从那个文件中读
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{ FILE *file = fopen("./test.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}fseek(file, 0, 2); //参数1是文件指针,参数2 0 表示偏移量为 0,参数3 2 表示从文件末尾开始偏移。int len = ftell(file);rewind(file); // 文件指针重置到文件的开头。char *info = (char *)calloc(1, len); //动态开辟内存 分配的内存大小为 len 个字节//从文件file 中读取数据到 info 所指向的内存中 len 表示每个数据块的大小(以字节为单位),1 表示要读取的数据块数量。if (fread(info, len, 1, file)!= 1) { printf("读取文件失败\n");free(info);fclose(file);return 1;}fclose(file); //关闭文件。printf("%s\n",info); //确保正确的字符串 以\0 结尾free(info);return 0;
}
8 fwrite 【**】
一次写n块
语法:
函数头stdio.h
函数size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:ptr:这是指向要被写入的元素数组的指针。size:这是要被写入的每个元素的大小,以字节为单位。nmemb: 这是元素的个数,每个元素的大小为 size 字节。stream:这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。
返回值:实际写入的块数
9 fprintf
作用 给文件中格式化输入内容
语法:
函数头:stdio.h
函数int fprintf(FILE *stream, const char *format, ...)
参数:stream:文件指针format:格式化字符串...:输出数据列表
返回值:成功:则返回写入的字符总数,失败:返回一个负数
10 fscanf
作用:
格式化读取
语法:
函数头:stdio.h
函数:int fscanf(FILE *stream, const char *format, ...)
参数:stream:文件指针format:格式化字符串...:输入数据列表
返回值:成功:该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回EOF
11 rewind 【**】
作用:
将游标移动到文件开始
函数头stdio.h
函数void rewind(FILE *stream)
参数指针文件
12 ftell 【**】
作用: 测试游标到文件开始位置的字节数
语法:
函数头:stdio.h
函数:long int ftell(FILE *stream)
参数:文件指针
返回值:文件读写位置距文件开始的字节数
#include <stdio.h>
int main(int argc, char const *argv[])
{FILE *file = fopen("./小说.txt","w+"); //以可读可写的方式打开fputs("张十一",file); // 写入一个字符串fseek(file,0,2); // 将游标移动到尾部 参数1 文件 参数2 偏移量 参数3 0 开始 1当前位置 2 尾部 int len = ftell(file); // 要 测量的文件指针printf("字节数 = %d\n",len);fclose(file); //关闭文件return 0;
}
13 fseek 【**】
作用:
移动游标位置
语法:
函数头:stdio.h
函数:int fseek(FILE *stream, long int offset, int whence)
参数:stream:文件指针offset:相对于whence的偏移量whence:位置,0,开始,1,当前位置,2,结尾
一次性读取文件中的所有内容
FILE *file = fopen("./test.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}fseek(file, 0, 2); //参数1是文件指针,参数2 0 表示偏移量为 0,参数3 2 表示从文件末尾开始偏移。int len = ftell(file);rewind(file); // 文件指针重置到文件的开头。char *info = (char *)calloc(1, len+1); //动态开辟内存 分配的内存大小为 len 个字节//从文件file 中读取数据到 info 所指向的内存中 len 表示每个数据块的大小(以字节为单位),1 表示要读取的数据块数量。if (fread(info, len, 1, file)!= 1) { printf("读取文件失败\n");free(info);fclose(file);return 1;}fclose(file); //关闭文件。printf("%s\n",info); //确保正确的字符串 以\0 结尾free(info);
2 makefile
概述:
编写编译命令的文件
文件编写格式
目标:依赖文件列表<Tab>命令列表解释:1、目标:通常是要产生的文件名称,目标可以是可执行文件或其它 obj 文件,也可是一个动作的名称2、依赖文件:是用来输入从而产生目标的文件一个目标通常有几个依赖文件(可以没有)3、命令:make 执行的动作,一个规则可以含几个命令(可以没有)有多个命令时,每个命令占一行
如:在makefile文件中编写
main:main.cgcc main.c -o main
clear:rm main
其中main就是目标,main.c就是依赖文件,gcc main.c -o main就是命令注意:当目标后没有依赖文件,我们将其称为假想目标
变量
分类
系统变量(了解)
由系统提供的变量make工具会拷贝系统的环境变量并将其设置为 makefile 的变量,在 makefile 中可直接读取或修改拷贝后的变量。查看系统变量命令 env修改或添加系统变量 export 变量名=值注意export是导入的意思注意:只是临时修改,也就是只在当前dos框中生效, 当dos关闭后,将不在存在 如:makefile编写如下 main:main.o myutils.ogcc main.o myutils.o -o main clear:rm main *.o myprint:echo ${PWD}
自定义变量
程序员在编写makefile文件中自定义的变量
预定义变量
make命令提供的变量
自定义变量
语法
定义变量名=变量值 使用取值:$(变量名)或${变量名}拼接:变量名+=值
注意:
> 1、makefile 变量名可以以数字开头 > 2、变量是大小写敏感的 > 3、变量一般都在 makefile 的头部定义 > 4、变量几乎可在 makefile 的任何地方使用
预定义变量
makefile 中有许多预定义变量,这些变量具有特殊的含义,可在 makefile 中直接使 用。$@ 目标名$< 依赖文件列表中的第一个文件$^ 依赖文件列表中除去重复文件的部分 以下为了解AR 归档维护程序的程序名,默认值为 arARFLAGS 归档维护程序的选项AS 汇编程序的名称,默认值为 asASFLAGS 汇编程序的选项CC C 编译器的名称,默认值为 gccCFLAGS C 编译器的选项CPP C 预编译器的名称,默认值为$(CC) -ECPPFLAGS C 预编译的选项CXX C++编译器的名称,默认值为 g++CXXFLAGS C++编译器的选项
编写模板
EXEC = 可执行程序名
OBJ = 二进制文件名列表
FLAGS = -Wall -g # 忽略一些警告$(EXEC):$(OBJ)
$(CC) $(OBJ) -o $(EXEC) $(-Wall -g)
二进制文件名1.o:源文件名1.c
$(CC) -c 源文件名.c -o 二进制文件名.o
二进制文件名2.o:源文件名2.c
$(CC) -c 源文件名.c -o 二进制文件名.o
clear:rm $(EXEC) *.o注意:源文件名与二进制文件名相同
示例:
EXEC = main
OBJ = main.o utils.o
FLAGS = -Wall -g
CC = gcc$(EXEC):$(OBJ)$(CC) $(OBJ) -o $(EXEC) $(-Wall -g)
main.o:main.c$(CC) -c main.c -o main.o
utils.o:utils.c$(CC) -c utils.c -o utils.o
clear:rm $(EXEC) *.o
3 make命令
概述
解析makefile文件的命令
检查make命令是否存在
- make --version
- which make
GNU Make名词
GNU make 是一种代码维护工具, make 工具会根据 makefile 文件定义的规则和步
骤,完成整个软件项目的代码维护工作
优点:
1、管理我们的源文件
2、会检查每个源文件是否被修改 只会再次只编译修改过的源文件(提高编译效
率)
缺点:
makefile文件:在Window上的集成开发环境下,会自动生成, 在Linux下需要手
动编写。
使用
语法:make 目标注意:目标可以没有,默认执行第一个目标注意:
1、make 默认在工作目录中寻找名为 GNUmakefile、makefile、Makefile 的文件作为 makefile 输入文件
2、-f 可以指定以上名字以外的文件作为 makefile 输入文件
3、若使用 make 命令时没有指定目标,则 make 工具默认会实现 makefile 文件内的第一个目标,然后退出。如:在控制台输入1,输入make,默认执行makefile文件中第一个目标中命令2,输入make 目标,执行makefile文件中指定的目标中的命令3,当makefile的文件名不是GNUmakefile、makefile、Makefile时,可以输入make -f 文件名,指makefile文件
make命令
概述
解析makefile文件的命令
检查make命令是否存在
- make --version
- which make
GNU Make名词
GNU make 是一种代码维护工具, make 工具会根据 makefile 文件定义的规则和步
骤,完成整个软件项目的代码维护工作
优点:
1、管理我们的源文件
2、会检查每个源文件是否被修改 只会再次只编译修改过的源文件(提高编译效
率)
缺点:
makefile文件:在Window上的集成开发环境下,会自动生成, 在Linux下需要手
动编写。
使用
语法:make 目标注意:目标可以没有,默认执行第一个目标注意:
1、make 默认在工作目录中寻找名为 GNUmakefile、makefile、Makefile 的文件作为 makefile 输入文件
2、-f 可以指定以上名字以外的文件作为 makefile 输入文件
3、若使用 make 命令时没有指定目标,则 make 工具默认会实现 makefile 文件内的第一个目标,然后退出。如:在控制台输入1,输入make,默认执行makefile文件中第一个目标中命令2,输入make 目标,执行makefile文件中指定的目标中的命令3,当makefile的文件名不是GNUmakefile、makefile、Makefile时,可以输入make -f 文件名,指makefile文件