C_13_FILE

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:只写
							特点:
								文件不存在,创建文件.文件存在清空文件原内容,在打开,文件打不开(:只读文件),返回NULL
                      a:追加
							特点:
								文件不存在,创建文件.文件存在原文件末尾操作              
                       +:  同时以读写打开指定文件
                           分类:
							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.c
	gcc 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.o
	gcc 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 归档维护程序的程序名,默认值为 ar
	ARFLAGS 归档维护程序的选项
	AS 汇编程序的名称,默认值为 as
	ASFLAGS 汇编程序的选项
	CC C 编译器的名称,默认值为 gcc
	CFLAGS C 编译器的选项
	CPP C 预编译器的名称,默认值为$(CC) -E
	CPPFLAGS 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文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值