c语言-文件的读写操作(上)

文章目录

  • 前言
  • 一、文件基础
    • 1.1 文件的分类
    • 1.2 文件路径和文件名
  • 二、文件的打开和关闭
    • 2.1 文件指针
    • 2.2 文件的打开和关闭
  • 三、文件顺序读写
    • 3.1 fputc()和fgetc()
    • 3.2 fputs()和fgets()
    • 3.3 fprintf()和fscanf()
    • 3.4 fwrite()和fread()
    • 3.4 对比一组函数
  • 总结


前言

本篇文章介绍c语言的文件读写操作。


一、文件基础

1.1 文件的分类

在c语言中,从文件的功能角度来看,文件可分为以下两类

  • 程序文件
    程序文件包含源文件(.c)、目标文件(.obj)、可执行文件(.exe)
  • 数据文件
    数据文件的内容是供程序运行时读/写(输入/输出)的数据;
    数据文件包含文本文件和二进制文件

1.2 文件路径和文件名

文件路径分为两类

  • 相对路径
  • 绝对路径

文件名包含3部分:文件路径(E:\cproject\advancedC)+文件名称(data)+文件后缀名(.txt)

E:\cproject\advancedC\data.txt

文件名作为文件的唯一标识,以便系统识别和使用。

二、文件的打开和关闭

2.1 文件指针

在缓冲文件系统中,每个被使用的文件 都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息(比如文件的名称,文件状态等)。通过定义一个结构体变量存储这些信息。这个结构体通过类型重名,命名为FILE。
每当打开一个文件时,操作系统根据文件的情况自动创建一个FILE类型的结构体变量,并填充结构中的信息。
一般通过一个FILE*类型的指针去维护文件信息。

FILE* pf; //文件指针变量

定义一个文件指针变量pf,pf可以指向某个文件的文件信息区。通过文件信息区中的信息能够访问pf的文件,即通过文件指针变量能够找到与其关联的文件。

2.2 文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在成功打开文件后,都会返回一个FILE*的指针变量并指向该文件,也相当于建立了指针和文件的关系。
ANSIC规定使用以下两个函数打开文件和关闭文件

//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );

fopen()参数说明

  • filename:要打开的文件名(包含路径)
  • mode:文件的打开模式
文件打开模式 含义 如果文件不存在
"r" 以只读的方式打开一个已存在的文本文件 出错
"w" 以只写的方式打开一个文本文件 建立一个新文件
"a" 向文本文件末尾追加数据 建立一个新文件
"rb" 以只读的方式打开一个二进制文件 出错
"wb" 以只写的方式打开一个二进制文件 建立一个新文件
"ab" 向二进制文件末尾追加数据 建立一个新文件
"r+" 以读写的方式打开一个文本文件 出错
"w+" 以读写的方式打开一个文本文件 建立一个新文件
"a+" 以读写的方式打开一个文本文件,在文件末尾进行读写 建立一个新文件
"rb+" 以读写的方式打开一个二进制文件 出错
"wb+" 以读写的方式打开一个二进制文件 建立一个新文件
"ab+" 以读写的方式打开一个二进制文件,在文件末尾进行读写 建立一个新文件

注意: 在使用文件之前,要对打开文件的进行判断是否打开成功

	//1.打开文件
	FILE* pf = fopen("data.txt", "w");
	//判断
	if (NULL == pf)
	{
		//利用perror()打印错误信息
		perror("fopen");
		return 1;
	}
	//2. 使用文件
	//....
	//3. 关闭文件
	fclose(pf);
	pf = NULL;

三、文件顺序读写

文件的读写操作分三步

第一步:打开文件
第二步:读/写文件
第三步:关闭文件

以下是c语言提供的库函数对文件读/写操作的支持

功能 函数名 操作对象
字符输入函数 fgetc() 所有输入流
字符输出函数 fputc() 所有输出流
字符串输入函数 fgets() 所有输入流
字符串输出函数 fputs() 所有输出流
格式化输入函数 fscanf() 所有输入流
格式化输出函数 fprintf() 所有输出流
二进制输入 fread() 文件
二进制输出 fwrite() 文件

任何一个c程序,只要运行起来就会默认打开三个流

  • stdin -> 标出输入流(键盘)
  • stdout->标准输出流(屏幕)
  • stderr->标准错误流(屏幕)

因此,在c程序中
可以直接使用scanf()直接接收键盘数据(stdin);
printf()直接将信息输出到屏幕(stdout);
perror()直接将错误信息输出到屏幕(stderr)。

3.1 fputc()和fgetc()

将一个字符写入文件

#include
 //fputc()向文件写入一个字符
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.txt", "w");
	if (NULL == pf)
	{
		//利用perror()打印错误信息
		perror("fopen");
		return 1;
	}
	
	//2. 读/写文件
	//向文件写入1个字符 fputc()
	char ch = 0;
	scanf("%c", &ch);
	fputc(ch,pf);
	
	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

从文件中读取一个字符

#include
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.txt", "r");

	if (NULL == pf)
	{
		//利用perror()打印错误信息
		perror("fopen");
		return 1;
	}
	//2. 读/写文件
	//读取文件1个字符 fgetc()
	int ch = fgetc(pf);
	printf("%c", ch);
	
	//3. 关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

3.2 fputs()和fgets()

将一个字符串写入文件

#include
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.txt","w"); 
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//2. 读/写文件
	//fputs()->写
	char str_write[20] = "Hi,PYSpring!";
	fputs(str_write,pf);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

从文件读取一个字符串

#include
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//2. 读/写文件
	//fgets()->读
	char str_read[20] = { 0 };
	fgets(str_read, sizeof(str_read), pf);
	printf("%s\n", str_read);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

3.3 fprintf()和fscanf()

定义一个结构体

typedef struct Student  //定义个学生结构体类型
{
	char student_number[20];  //学号
	char student_name[20];   //名字
	int age;                 //年龄
} Student;

将格式化数据写入文件

#include
int main()
{
	
	//1. 打开文件
	FILE* pf = fopen("data.txt","w");
	if (NULL == pf)
	{
		perror("fopen()");
		return 1;
	}
	//2. 读/写文件
	//写
	Student student = {"20240125","PYSpring", 24};
	fprintf(pf,"%s %s %d",student.student_number,student.student_name, student.age);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

从文件读取格式化数据

#include
int main()
{

	//1. 打开文件
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen()");
		return 1;
	}
	//2. 读/写文件
	//读
	Student tmp = { 0 };
	fscanf(pf, "%s %s %d", tmp.student_number, tmp.student_name, &(tmp.age));
	printf("学号:%s\n姓名:%s\n年龄: %d\n", tmp.student_number, tmp.student_name, tmp.age);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

3.4 fwrite()和fread()

将数据以二进制形式写入到一个二进制文件中

#include
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.bin","wb");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//2. 读/写文件
	// fwrite()以二进制形式写入
	Student student = { "20240125","PYSpring66", 24 };
	fwrite(&student,sizeof(Student),1,pf);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

从一个二进制文件以二进制形式读取数据

#include
int main()
{
	//1. 打开文件
	FILE* pf = fopen("data.bin","rb");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//2. 读/写文件
	// fwrite()以二进制形式写入
	Student student = { 0 };
	fread(&student,sizeof(Student),1,pf);
	printf("学号:%s\n姓名:%s\n年龄: %d\n", student.student_number, student.student_name, student.age);
	
	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

3.4 对比一组函数

  • scanf()、fscanf()、sscanf()
    scanf() ->针对标准输入的格式化输入
    fscanf() ->针对所有输入流的格式化输入
    sscanf() ->从一个字符串中转化成一个格式化数据
  • printf()、fprintf()、sprintf()
    printf() ->针对标准输出的格式化输出
    fprintf() ->针对所有输出流的格式化输出
    sprintf() ->将一个格式化数据转化为字符串

总结

本篇文章介绍了文件的打开与关闭,最后介绍文件的顺序读写操作。

你可能感兴趣的:(c语言进阶,c语言)