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程序,只要运行起来,就会默认打开3个流。
有以下3种标准流:

stdin ------- 标准输入流 -------- 用于读取从键盘中输入的数据
stdout ------- 标准输入流 -------- 用于写入数据至显示器界面
stderr ------- 标准错误流 -------- 用于写出错误至显示器界面

下面我们来谈谈什么是文件:

在程序设计中,按文件功能的角度来分类有两种:程序文件和数据文件。
程序文件:包括源程序文件(.c)、目标文件(.obj)、可执行程序(.exe)、
数据文件:程序运行中需要读取数据和输出内容的文件。

本文讨论的就是数据文件


三、文件的使用

1、文件指针

在程序我们应该怎样使用文件?

在计算机中,每个被使用的文件都会在内存中开辟一个相应的文件信息区,用来存放相关信息。这些信息一般以结构体的形式实现,是由系统声明的,取名为FILE。

下面我们可以创建一个FILE*的指针变量:

FILE* pf;

可以通过文件指针变量来找到与他关联的文件
在这里插入图片描述


2、文件的打开和关闭

在读写文件前,都应该先打开文件,在使用完毕之后就要关闭文件
ANSIC规定使用fopen函数来打开文件,fclose来关闭文件

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

文件打开方式如下:

打开方式含义
“r”(只读)以只读模式打开一个已存在的文件,若指定文件不存在,则出错
“w”(只写)以只写模式建立一个文件,若指定文件不存在,则新建一个文件
“a”(追加)以追加模式向文件末尾写入数据,若指定文件不存在,则新建一个文件
“rb”(只读)以只读模式打开一个二进制文件,若指定文件不存在,则出错
“wb”(只写)以只写模式建立一个二进制文件,若指定文件不存在,则新建一个文件
“ab”(追加)以追加模式向二进制文件末尾写入数据,若指定文件不存在,则出错
“r+”(读写)以更新(读写)模式打开一个文本文件,若指定文件不存在,则出错
“w+”(读写)以更新(读写)模式建立一个新文件,若指定文件不存在,则新建一个文件
“a+”(读写)以追加模式打开一个文件,在末尾进行读写,若指定文件不存在,则新建一个文件
“rb+”(读写)以更新(读写)模式打开一个二进制文件,若指定文件不存在,则出错
“wb+”(读写)以更新(读写)模式建立一个二进制文件,若指定文件不存在,则新建一个文件
“ab+”(读写)以追加模式打开一个二进制文件,在末尾进行读写,若指定文件不存在,则新建一个文件

举个例子:

#include <stdio.h>

int main()
{
    //打开文件
    FILE* pf = fopen("text.txt", "w");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    //读写文件

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

3、文件的读写

文件的读写分为两种:顺序读写和随机读写

3.1、顺序读写

下面我们先介绍文件是如何顺序读写?
文件在顺序读写时,会用以下函数进行读写:

函数功能
fgetc字符输入函数
fputc字符输出函数
fgets文本输入函数
fputs文本输出函数
fscanf格式化输入函数
fprintf格式化输出函数
fread二进制输入
fwrite二进制输出

以上函数除了fread和fwrite函数只适用于文件,其余函数均可适用于所以输入输出流。

在这里插入图片描述


3.1.1、字符输入输出函数

int fputc( int character, FILE * stream );
int fgetc ( FILE * stream );

举个例子(写文件):

#include <stdio.h>

int main()
{
    //打开文件
    FILE* pf = fopen("text.txt", "w");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    //写文件
    int i = 0;
    for (i = 0; i < 26; i++)
    {
        fputc('a' + i, pf);
    }
    //关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

在这里插入图片描述
举个例子(读文件):

#include <stdio.h>

int main()
{
    //打开文件
    FILE* pf = fopen("text.txt", "r");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    //读文件
    int ch = fgetc(pf);
    printf("%c\n", ch);
    //关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}

文件中的数据:
在这里插入图片描述
读取结果:

在这里插入图片描述


3.1.2、文本输入输出函数

int fputs ( const char * str, FILE * stream );
char * fgets ( char * str, int num, FILE * stream );

举个例子(写文件):

//写文件
    fputs("hello\n", pf);
    fputs("word", pf);

在这里插入图片描述
举个例子(读文件):

	//读文件-一行一行读
	char arr[8] = "########";
	fgets(arr, 5, pf);
	printf("%s\n", arr);

文件中的数据:
在这里插入图片描述
读取结果:
在这里插入图片描述
在这里插入图片描述
代码若改为:

    //读文件-一行一行读
	char arr[8] = "########";
	fgets(arr, 8, pf);
	printf("%s\n", arr);

结果为:
在这里插入图片描述
在这里插入图片描述


3.1.3、格式化输入输出函数

int fprintf ( FILE * stream, const char * format, … );
int fscanf ( FILE * stream, const char * format, … );

举个例子(写文件):

#include <stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "zhangsan",20,95.5f };
	//打开文件
	FILE* pf = fopen("text.txt", "w");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fprintf(pf, "%s %d %f", s.name, s.age, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
举个例子(读文件):

#include <stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %f\n", s.name, s.age, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件中的数据:
在这里插入图片描述
读取结果:
在这里插入图片描述


3.1.4、二进制输入输出函数

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

举个例子(写文件):

#include <stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "zhangsan",20,95.5f };
	//打开文件
	FILE* pf = fopen("text.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&s, sizeof(s), 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

由于是二进制写入,以文本形式显示,就会出现以上效果,但是以二进制读取,便会读取相应的结果。

代码如下(读文件):

#include <stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };
	//打开文件
	FILE* pf = fopen("text.txt", "rb");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fread(&s, sizeof(s), 1, pf);
	printf("%s %d %f", s.name, s.age, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述


3.1.5、几个函数的对比

scanf()等价于fgetc(stdin);
printf()等价于fputc(ch,stdout);

举个例子:

#include <stdio.h>

int main()
{
	char ch = fgetc(stdin);
	fputc(ch, stdout);
	return 0;
}

在这里插入图片描述

scanf:按照一定的格式从键盘输入数据
printf:按照一定的格式把数据打印(输出)到屏幕上
这两个函数适用于标准输入输出流的格式化的输入输出语句

fscanf:按照一定的格式从输入流(文件/stdin)输入数据
fprintf:按照一定的格式向输出流(文件/stdout)输出数据
这两个函数适用于所以的输入输出流的格式化输入输出语句

下面我们先举个例子了解 sprintfsscanf 函数

int sprintf ( char * str, const char * format, … );
int sscanf ( const char * s, const char * format, …);

代码如下:

#include <stdio.h>

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	char buf[100] = { 0 };
	struct S tmp = { 0 };
	struct S s = { "zhangsan",20,95.5f };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score); // 以字符串的形式打印
	printf("%s\n", buf);

	sscanf(buf, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score)); // 以结构体的形式打印
	printf("%s %d %f", tmp.name, tmp.age, tmp.score);
	return 0;
}

在这里插入图片描述

sscanf:从字符串中按照一定的格式读取出格式化的数据
sprintf:把格式化的数据按照一定的格式转换成字符串


3.2、随机读写

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

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

举个例子:

#include <stdio.h>

int main()
{
	
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fseek(pf, 3, SEEK_SET); // 从起始位置偏移3个位置
	int ch = fgetc(pf);
	printf("%c", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件中的数据:
在这里插入图片描述
读取结果:
在这里插入图片描述

函数中的 origin 参数用作偏移量参考的位置。

有如下3种常量用作此函数参数:

常数原始位置
SEEK_SET从起始位置开始偏移
SEEK_CUR从当前位置开始偏移
SEEK_END从文件结尾向前偏移

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

long int ftell ( FILE * stream );

举个例子:

#include <stdio.h>

int main()
{
	
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fseek(pf, 3, SEEK_SET); // 从起始位置偏移3个位置
	int ch = fgetc(pf);
	printf("%c\n", ch); //d
	int pos = ftell(pf);
	printf("%d", pos); //4
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
3.2.3、rewind
让文件指针的位置回到文件的起始位置

void rewind ( FILE * stream );


4、文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件二进制文件

在文本文件中,数据是以字符序列的形式来表示的。
在二进制文件中,数据是以二进制位的形式来表示的。

以10000为例:
在这里插入图片描述
由此可见:

文本文件中字符数取决于数值位数。
二进制文件中字符数(字节数)不依赖于数值位数


5、文件读取结束的判定

fgetc:? 如果读取正常,会返回读取到的字符的ASCII值。
? ? ? ???如果读取失败,返回EOF。
fgets:? 如果读取正常,返回的是存放读取到的数据的地址。
? ? ? ???如果读取失败,返回NULL。
fscanf: 如果读取正常,返回的是格式串中指定的数据的个数。
? ? ? ???如果读取失败,返回的是小于格式串中指定的数据的个数。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:13:43  更:2022-10-17 12:17:37 
 
开发: 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年5日历 -2024/5/19 5:06:12-

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