IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c语言文件操作 -> 正文阅读

[C++知识库]c语言文件操作

c语言的文件操作

什么是文件

磁盘上的文件是文件。
但是在程序设计的过程中,我们一般谈的文件有两种:程序文件、数据文件

程序文件

包括源程序文件(后缀为.c),目标文件(后缀为.obj),可执行程序(后缀为.exe)

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件

本博客讨论的是数据文件:

文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
文件标识常被称为文件名

文件指针

每个被使用的的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字、文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中。该结构体类型是有系统声明的,取名为FILE
下图是vs2018编译环境提供的stdio.h头文件中有以下文件类型的声明:
在这里插入图片描述
不同编译器包含的的内容不完全相同,但是大同小异。
每当我们打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

文件指针的定义:

FILE* pf;

文件操作:
在这里插入图片描述
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(结构体变量)。通过该文件信息区就可以访问该文件。也就是说,通过文件指针变量能够找到与它相关联的文件。

文件的类型

根据文件的组织形式,数据文件可以被分为文本文件或者二进制文件
二进制文件: 数据在内存中以二进制形式村删除,并不加转换的输出到外存
文本文件: 外存以ascii码的形式存储。
当然以两种形式存储文件的大小也不一样

文件缓冲区

所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块”文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
在这里插入图片描述

文件的打开和关闭**

c语言用两个函数来分别打开和关闭文件:

fopen

FILE *fopen( const char *filename, const char *mode );

返回值:
返回的是打开文件的指针,如果打开失败就返回空指针(NULL)
函数参数

  1. filename:要打开的文件的文件指针
  2. mode:一些操作指令,例如:
    在这里插入图片描述
int main()
{
	FILE* pf;
	pf = fopen("kksk.txt", "w");
	if (pf != NULL)
	{
		printf("打开文件成功");
		fclose(pf);
	}
	return 0;
}

这样一个文件以写入的方式就打开了,如果我们想要以读的方式打开文件

pf = fopen("kksk.txt", "r");

或者在找到文件的绝对路径

在这里插入图片描述
将绝对路径复制到文件指针处,但是记得把’ / ‘替换成’ // ',防止形成转义字符

pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "r");

文件的顺序读写

在这里插入图片描述

字符输入、输出函数

fgetc

适用所有输入流

int fgetc( FILE *stream );

功能:
每次从此刻文件指针指向的位置中读取一个字符。
返回值:
返回的是读取的字符的ACSII码值或者EOF来表明文件读取结束。

int main()
{
	FILE* pf;
	pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "r");
	if (pf != NULL)
	{
		printf("打开文件成功");

		int ret = 0;

		ret = fgetc(pf);
		printf("%c\n", ret);

		ret = fgetc(pf);
		printf("%c\n", ret);

		ret = fgetc(pf);
		printf("%c\n", ret);

		ret = fgetc(pf);
		printf("%c\n", ret);

		ret = fgetc(pf);
		printf("%c\n", ret);


		fclose(pf);
	}
	return 0;
}

如果事先在文件中输入abcd,然后编写程序读取就会有以下结果:
在这里插入图片描述
虽然文件中只有四个字符,但是第五次读取时ret的值等于-1(EOF)标志文件结束在这里插入图片描述

fputc

适用于所有输出流

int fputc( int c, FILE *stream );

返回值:
返回的是写入的字符,如果返回的是EOF表面写入失败
函数参数:
c:是带写入的字符
stream:是文件指针

文本行输入、输出函数

fgets

适用于所有输入流

char *fgets( char *string, int n, FILE *stream );

函数返回值
返回string,读到文件结尾返回NULL
函数参数:
string:存储字符串的地址
n:读入字符的最大数目,实际读入的是n-1个字符+’\0’
stream:读入数据的文件指针

fputs

int fputs( const char *string, FILE *stream );

函数返回值:
如果输入成功返回一个非零的数,如果输入失败返回EOF
函数参数:
string:要输入的字符串的地址
stream:文件的指针

格式化输入、输出函数

fprintf

实用所有的输出流

int fprintf( FILE *stream, const char *format [, argument ]... );

fprintf和printf的形式十分类似,只要在printf里面加一个文件指针即可


struct s
{
	int i;
	char b;
	char d[20];
};
int main()
{
	struct s a = { 10,'c',"kksk" };
	FILE* pf;
	pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "w");
	if (pf != NULL)
	{

		printf("打开文件成功\n");

		int ret = 0;
		fprintf(pf, "%d,%c,%s", a.i, a.b, a.d);

		fclose(pf);
	}
	return 0;
}

在这里插入图片描述
fprintf的最大优点可以一次性输入类型不同的数据

fscanf

适用于所有输入流

int fscanf( FILE *stream, const char *format [, argument ]... );

fscanf和scanf十分相像


struct s
{
	int i;
	char b;
	char d[20];
};
int main()
{
	struct s a = { 0};
	FILE* pf;
	pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "r");
	if (pf != NULL)
	{

		printf("打开文件成功\n");

		int ret = 0;
		fscanf(pf,"%d %c %s", &(a.i), &(a.b), a.d);
		printf("%d %c %s", a.i, a.b, a.d);
		fclose(pf);
	}
	return 0;
}

在这里插入图片描述

二进制输入、输出

前面所有的所有函数都是以文本的形式输入文件

fwrite

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

函数返回值:
返回的是实际写入的元素的个数,如果写入的元素个数小于count返回就会出现错误
函数参数:
buffer:指向要写的数据的指针
size:要写的元素的大小
count:要写的size大小的元素的个数
stream:要写到的文件指针



struct s
{
	int i;
	char b;
	char d[20];
};
int main()
{
	struct s a = { 10,'c',"sfdfqwdqd"};
	struct s c = { 0 };
	FILE* pf;
	pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "w");
	if (pf != NULL)
	{

		printf("打开文件成功\n");
		fwrite(&a, sizeof(struct s), 1, pf);
		fclose(pf);
	}
	return 0;
}

在这里插入图片描述
结构体a的数据以二进制的形式存入了文件

fread

函数返回值:
返回的是实际读取的元素的个数,如果写入的元素个数小于count返回就会出现错误并停止读取
函数参数:
buffer:指向要写的数据的指针
size:要写的元素的大小
count:要写的size大小的元素的个数
stream:要写到的文件指针

struct s
{
	int i;
	char b;
	char d[20];
};
int main()
{
	struct s a = { 10,'c',"sfdfqwdqd"};
	struct s c = { 0 };
	FILE* pf;
	pf = fopen("D:\\学习资料\\比特教育\\源代码\\Project1\\Project1\\kksk.txt", "r");
	if (pf != NULL)
	{
		printf("打开文件成功\n");
		fread(&c, sizeof(struct s), 1, pf);
		printf("%d %c %s", c.i, c.b, c.d);
		fclose(pf);
	}
	return 0;
}
scanf针对标准输入的格式化输入语句
pritnf针对标准输出的格式化输入语句
fscanf针对所有输入的格式化输入语句
fprintf针对所有输出的格式化输入语句
sscanf把一个字符串转换成格式化数据
spritnf把一个格式化数据转换成字符串

补充

scanf和sprintf

完成格式化数据->字符串->格式化数据的转换

struct S
{
	int a;
	char b;
	char c[20];
};
int main()
{
	struct S m = { 10,'c',"ssssssssssss" };
	struct S n = { 0 };
	char buffer[100];
	sprintf(buffer, "%d %c %s", m.a, m.b, m.c);
	printf("%s\n",buffer);
	sscanf(buffer, "%d %c %s", &(n.a), &(n.b), n.c);
	printf("%d %c %s", n.a, n.b, n.c);

}

在这里插入图片描述

文件的随机读写

fseek

根据文件指针的位置和偏移量来定位文件指针

int fseek( FILE *stream, long offset, int origin );

函数参数:
offset:偏移量
origin:起始位置分为如下指令:

  • SEEK_CUR:当前指针 的位置
  • SEEK_END:从文件的结尾开始
  • SEEK_SET:从文件的起始位置开始偏移

ftell

返回文件指针相对于起始位置的偏移量

long ftell( FILE *stream );

rewind

让文件指针的位置回到文件的起始位置

void rewind( FILE *stream );

文件结束判断

被错误使用的feof
牢记:在文件读取过程中,不能用eof的返回值判断文件是否读取结束。
eof适用于判断当文件读取结束的原因:读取失败结束 或 遇到文件结尾结束

判断文件读取结束的方法:利用函数的返回值

  1. 文本文件读取是否结束,判断返回值是否为EOF,或者空指针

    - fetc函数读取结束时,会返回EOF。其他正常读取时返回读取的字符的阿斯克码值
    - fgets函数读取结束时,会返回NULL。其他正常读取时返回读取的字符串的起始地址
    
在这里插入代码片
  1. 二进制文件读取结束判断,判断返回值是否小于实际要读的个数
    fread函数读取的时候返回的是实际读取的完整元素的个数,如果发现读取到的完整元素个数小于指定元素个数,就是最后一次读取
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-15 15:19:21  更:2021-08-15 15:19:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 17:33:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计