C++文件和流
到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。
本教程介绍如何从文件读取流和向文件写入流。这就需要用到 C++ 中另一个标准库 fstream,它定义了三个新的数据类型:
| 数据类型 | 描述 |
|---|---|
| ofstream | 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 |
| ifstream | 该数据类型表示输入文件流,用于从文件读取信息。 |
| fstream | 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
要在 C++ 中进行文件处理,必须在 C++ 源代码文件中包含头文件 <iostream> 和 <fstream>。
一、打开文件
在从文件读取信息或者向文件写入信息之前,必须先打开文件。ofstream 和 fstream 对象都可以用来打开文件进行写操作,如果只需要打开文件进行读操作,则使用 ifstream 对象。
下面是 open() 函数的标准语法,open() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。
void open(const char *filename, ios::openmode mode);
在这里,open() 成员函数的第一参数指定要打开的文件的名称和位置,第二个参数定义文件被打开的模式。
| 模式标志 | 描述 |
|---|---|
| ios::app | 追加模式。所有写入都追加到文件末尾。 |
| ios::ate | 文件打开后定位到文件末尾。 |
| ios::in | 打开文件用于读取。 |
| ios::out | 打开文件用于写入。 |
| ios::trunc | 如果该文件已经存在,其内容将在打开文件之前被截断,即把文件长度设为 0。 |
您可以把以上两种或两种以上的模式结合使用。例如,如果您想要以写入模式打开文件,并希望截断文件,以防文件已存在,那么您可以使用下面的语法:
ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );
类似地,您如果想要打开一个文件用于读写,可以使用下面的语法:
ifstream afile;
afile.open("file.dat", ios::out | ios::in );
1.2 示例
`ofstream outfile` 是定义了一个名为 `outfile` 的输出文件流对象,用于将数据写入磁盘上的文件。可以使用 `<<` 运算符向文件写入数据,例如:
#include<iostream>
#include<fstream>
int main(){std::ofstream outfile("example.txt"); // 打开文件outfile << "Hello, world!" << std::endl; // 向文件写入数据outfile.close(); // 关闭文件
}
在这个例子中,`outfile` 对象被创建并打开了 `example.txt` 文件(文件的路径可以指定,在上述程序中,我们没有指定文件的路径,则该文件会存放在该程序所存放的文件夹位置中),然后使用 `<<` 运算符向文件写入了 `"Hello, world!"` 字符串以及一个换行符,最后关闭了文件。该文件如打开如下图所示。

需要注意的是,如果文件不存在,则会创建该文件;如果文件已存在,则会将其覆盖。
`ifstream afile;` 是定义了一个名为 `afile` 的输入文件流对象,用于从磁盘上的文件读取数据。可以使用 `>>` 运算符从文件读取数据,例如:
#include<iostream>
#include<fstream>
#include<string>
int main() {std::ifstream afile("example.txt"); // 打开文件std::string line;while (std::getline(afile, line)) { // 逐行读取文件内容 注意:必须引入<string>头文件才能正确使用getline函数std::cout << line << std::endl; // 输出每一行内容}afile.close(); // 关闭文件}
在这个例子中,`afile` 对象被创建并打开了 `example.txt` 文件,然后使用 `getline()` 函数将文件内容逐行读取到字符串变量 `line` 中,并输出到标准输出流中。最后关闭了文件。
上述程序输出结果:

需要注意的是,如果文件打开成功,则可以继续读取文件内容;如果文件不存在或无法打开,则需要进行错误处理。在读取文件时,可以根据具体需求选择不同的读取方式和处理方法来读取所需的数据。
关闭文件
当 C++ 程序终止时,它会自动关闭刷新所有流,释放所有分配的内存,并关闭所有打开的文件。但程序员应该养成一个好习惯,在程序终止前关闭所有打开的文件。
下面是 close() 函数的标准语法,close() 函数是 fstream、ifstream 和 ofstream 对象的一个成员。
void close();
写入文件
在 C++ 编程中,我们使用流插入运算符( << )向文件写入信息,就像使用该运算符输出信息到屏幕上一样。唯一不同的是,在这里您使用的是 ofstream 或 fstream 对象,而不是 cout 对象。
读取文件
在 C++ 编程中,我们使用流提取运算符( >> )从文件读取信息,就像使用该运算符从键盘输入信息一样。唯一不同的是,在这里您使用的是 ifstream 或 fstream 对象,而不是 cin 对象。
文件位置指针
在 C++ 中,文件位置指针(File Position Pointer)用于标识当前读写位置在文件中的位置。C++ 标准库提供了两个主要的文件位置指针类型:std::ifstream 和 std::ofstream,分别用于输入流和输出流。
ifstream 和 ofstream 都提供了用于重新定位文件位置指针的成员函数。这些成员函数包括关于 ifstream 的 seekg("seek get")和关于 ofstream 的 seekp("seek put")。
seekg 和 seekp 的参数通常是一个长整型。第二个参数可以用于指定查找方向。查找方向可以是 ios::beg(默认的,从流的开头开始定位),也可以是 ios::cur(从流的当前位置开始定位),也可以是 ios::end(从流的末尾开始定位)。
文件位置指针是一个整数值,指定了从文件的起始位置到指针所在位置的字节数。下面是关于定位 "get" 文件位置指针的实例:
// 定位到 fileObject 的第 n 个字节(假设是 ios::beg)
fileObject.seekg( n );// 把文件的读指针从 fileObject 当前位置向后移 n 个字节
fileObject.seekg( n, ios::cur );// 把文件的读指针从 fileObject 末尾往回移 n 个字节
fileObject.seekg( n, ios::end );// 定位到 fileObject 的末尾
fileObject.seekg( 0, ios::end );
文件位置指针主要有以下三种操作:
<1> 定位到文件开头(seekg(0) / seekp(0)):
std::ifstream inputFile("example.txt");
inputFile.seekg(0); // 将输入文件位置指针定位到文件开头std::ofstream outputFile("example.txt");
outputFile.seekp(0); // 将输出文件位置指针定位到文件开头
seekg(0) 和 seekp(0) 将文件位置指针移动到文件的开头。
<2> 移动相对位置(seekg(offset, direction) / seekp(offset, direction)):
std::ifstream inputFile("example.txt");
inputFile.seekg(10, std::ios::cur); // 相对于当前位置向前移动 10 个字节std::ofstream outputFile("example.txt");
outputFile.seekp(-5, std::ios::end); // 相对于文件末尾向后移动 5 个字节
seekg(offset, direction) 和 seekp(offset, direction) 可以在文件中移动位置指针。offset 表示要移动的偏移量,可以是正数或负数。direction 指定了移动的方向,可以使用以下值:
std::ios::beg:相对于文件开头进行偏移,默认值。std::ios::cur:相对于当前位置进行偏移。std::ios::end:相对于文件末尾进行偏移。
<3> 定位到文件末尾(seekg(0, std::ios::end) / seekp(0, std::ios::end)):
std::ifstream inputFile("example.txt");
inputFile.seekg(0, std::ios::end); // 将输入文件位置指针定位到文件末尾std::ofstream outputFile("example.txt");
outputFile.seekp(0, std::ios::end); // 将输出文件位置指针定位到文件末尾
seekg(0, std::ios::end) 和 seekp(0, std::ios::end) 将文件位置指针移动到文件的末尾。
注意:文件位置指针操作需要在打开文件后才能使用。另外,对于二进制文件,应该使用 std::ios::binary 模式打开文件来确保精确的指针操作。
示例
#include<iostream>
#include<fstream>int main() {std::ofstream outfile("D:/桌面资料/研究生阶段/C++Learning_road/C++file_test/example.txt"); // 打开文件outfile << "Hello, world!"; // 向文件写入数据outfile.seekp(0); // 将文件位置指针移动到文件的开头outfile.seekp(5, std::ios::cur); // 相对于当前位置向前移动 5 个字节 outfile << "世界,你好!" << std::endl; // 向文件写入数据outfile.close(); // 关闭文件return 0;
}
运行上述程序,得到如下结果:

程序分析:
这段代码首先创建了一个名为 "D:/桌面资料/研究生阶段/C++Learning_road/C++file_test/example.txt" 的文件输出流对象 `outfile`,然后向文件中写入了字符串 "Hello, world!"。接下来,代码将文件位置指针移动到文件开头,然后相对于当前位置向前(向前的原理如下图所示)移动 5 个字节。最后,代码向文件中写入了字符串 "世界,你好!" 并添加了一个换行符。
需要注意的是,`seekp(0)` 将文件位置指针移动到文件开头,然后 `seekp(5, std::ios::cur)` 将文件位置指针相对于当前位置向前移动 5 个字节,因此,最终的文件位置指针指向了字符 'w'。
通过执行这段代码,你将会在指定路径的 example.txt 文件中得到以下内容:
Hello世界,你好!
最后,通过调用 `outfile.close()` 关闭文件。关闭文件是一个好的习惯,可以确保文件资源被正确释放,同时也可以确保文件的写入操作已经完成。

相关文章:
C++文件和流
到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。 本教程介绍如何从文件读取流和向文件写入流。这就需要用到 C 中另一个标准库 fstream,它定义了三个新的数据类型&#x…...
代码随想录算法训练营第23期day31|贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和
目录 一、贪心算法理论基础 二、(leetcode 455)分发饼干 三、(leetcode 376)摆动序列 四、(leetcode 53)最大子序和 一、贪心算法理论基础 1.什么是贪心 贪心的本质是选择每一阶段的局部最优…...
mdadm命令详解及实验过程
mdadm命令详解及实验过程 ⼀.概念 mdadm是multiple devices admin的简称,它是Linux下的⼀款标准的软件 RAID 管理⼯具,作者是Neil Brown ⼆.特点 mdadm能够诊断、监控和收集详细的阵列信息 mdadm是⼀个单独集成化的程序⽽不是⼀些分散程序的集合&#…...
推荐几个程序员必逛的个人技术博客网站
1、美团技术团队 地 址: 美团技术团队简 介:美团技术团队的博客,干货满满。推荐指数:⭐⭐⭐⭐⭐ 2、阮一峰的网络日志 地 址: 阮一峰的个人网站 - Ruan YiFengs Personal Website简 介:大神阮一峰,博客风格真正…...
Python桌面应用之XX学院水卡报表查询系统(Tkinter+cx_Oracle)
一、功能样式 Python桌面应用之XX学院水卡报表查询系统功能: 连接Oracle数据库,查询XX学院水卡操作总明细报表,汇总数据报表,个人明细报表,进行预览并且支持导出报表 1.总明细报表样式 2.汇总明细样式 3.个人明细…...
ubuntu 中使用Qt连接MMSQl,报错libqsqlodbc.so: undefined symbol: SQLAllocHandle
Qt4.8.7的源码编译出来的libqsqlodbc.so,在使用时报错libqsqlodbc.so: undefined symbol: SQLAllocHandle,需要在编译libqsqlodbc.so 的项目pro文件加上LIBS -L/usr/local/lib -lodbc。 这里的路径根据自己的实际情况填写。 编辑: 使用uni…...
笔试,猴子吃香蕉,多线程写法
package demo;import java.util.concurrent.CountDownLatch;/*** description: 猴子吃香蕉* author: wxm* create: 2023-10-23 14:01**/ public class Main {public static void main(String[] args) throws InterruptedException {Monkey[] m new Monkey[3];Resource r new …...
安装docker ,更换docker版本
docker dockerd & containerd Dockerd(Docker 守护进程)在其底层使用 Containerd 来管理容器。Containerd 是一个开源的容器运行时管理器,由 Docker 公司于2017年开发并开源,它负责实际的容器生命周期管理。 以下是 Docker 守…...
英语小作文写作模板及步骤(1)
...
编写hello驱动程序
hello的驱动编写 编写驱动程序的步骤 1.确定主设备号,也可以让内核分配 2.定义自己的 file_operations 结构体 3.实现对应的 drv_open/drv_read/drv_write 等函数,填入 file_operations 结构 体 4.把 file_operations 结构体告诉内核:regist…...
ZYNQ中断例程
GPIO 中断系统初始化流程: 第一步:初始化 cpu 的异常处理功能 第二步:初始化中断控制器 第三步:向 CPU 注册异常处理回调函数; 第四步:将中断控制器中的对应中断 ID 的中断与中断控制器相连接 第五步:设置 …...
常用linux命令 linux_cmd_sheet
查看文件大小 ls -al 显示每个文件的kb大小 查看系统日志 dmesg -T | tail 在 top 命令中,RES 和 VIRT(或者 total-vm)是用来表示进程内存使用的两个不同指标,它们之间有以下区别: RES(Resident Set Size…...
【proteus】8086 写一个汇编程序并调试
参考书籍:微机原理与接口技术——基于8086和Proteus仿真(第3版)p103-105,p119-122. 参考程序是p70,例4-1 在上一篇的基础上: 创建项目和汇编文件 写一个汇编程序并编译 双击8086的元件图: …...
大数据之LibrA数据库常见术语(四)
Failover 指当某个节点出现故障时,自动切换到备节点上的过程。反之,从备节点上切换回来的过程称为Failback。 Freeze 在事务ID耗尽时由AutoVacuum Worker进程自动执行的操作。FusionInsight LibrA会把事务ID记在行头,在一个事务取得一行时&…...
Docker基础知识
文章目录 Docker Docker 一次构建,处处运行,类似于JVM 虚拟机是软件硬件(需要Hypervisors实现硬件资源虚拟化): 资源占用大启动慢(虚拟机是分钟级,Docker是秒级)冗余步骤多 sha2…...
swoole 是什么?
Swoole是一个为PHP用C和C编写的基于事件的高性能异步& 协程并行网络通信引擎; 使 PHP 开发人员可以编写高性能的协程 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IO…...
我想要一个勋章
目录 一、背景二、过程三、总结 一、背景 十年前结缘,也许是冥冥中自有天注定,注定要给自己多加一个今天的节日。 二、过程 一个勋章,一个有意义的标志。 一个勋章,一个时间轮上的帧。 一个勋章,一个二进制的节点。…...
微信小程序设计之主体文件app-json-pages
一、新建一个项目 首先,下载微信小程序开发工具,具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后,注册小程序账号,具体注册方法,可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…...
C语言-面试题实现有序序列合并
要求: a.输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。 数据范围: 1≤n,m≤1000 1≤n,m≤1000 , 序列中的值满足 0≤val≤30000 输入描述: 1.输入包含三行, 2.第一行包含两个正整数n, m&am…...
Android12 启动页适配
印象中,在2022年末接到了一个针对Android12启动页适配的需求,当时也使用了一些适配方案,也写了一个Demo,但是最终没有付诸适配行动;当然并不是适配失败,而是根据官方适配方案适配后太丑了… 1024纪念文章&a…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
