C++中IO文件输入输出知识详解和注意事项

以下内容将从文件流类体系打开模式文本与二进制 I/O随机访问错误处理性能优化等方面,详解 C++ 中文件输入输出的使用要点,并配以示例。


一、文件流类体系

C++ 标准库提供三种文件流类型,均定义在 <fstream> 中:

  • std::ifstream:输入文件流,用于从文件读取(继承自 std::istream)。
  • std::ofstream:输出文件流,用于向文件写入(继承自 std::ostream)。
  • std::fstream:读写文件流,可同时做输入和输出(继承自两者)。

它们的典型用法与标准流 (cin/cout) 类似,但需要先打开文件。


二、打开模式(std::ios_base::openmode

打开时可指定下列模式的按位或(|)组合:

模式含义
std::ios::in打开用于读操作
std::ios::out打开用于写操作
std::ios::app所有写操作均追加到文件末尾
std::ios::trunc打开时清空已有内容(默认对 ofstream 生效)
std::ios::binary二进制模式(屏蔽文本模式下的换行转换)
std::ios::ate打开后立即定位到文件末尾

示例:

std::ifstream fin("data.txt", std::ios::in);
std::ofstream fout("out.txt", std::ios::out | std::ios::trunc);
std::fstream fs("db.bin", std::ios::in|std::ios::out|std::ios::binary);

三、文本文件 I/O

1. 写入文本

  • operator<< 与格式化

    std::ofstream fout("log.txt");
    fout << "Count = " << count << '\n';
    
  • std::endl'\n'

    • std::endl 会插入换行并刷新缓冲,频繁使用有性能开销;推荐输出 '\n'

2. 读取文本

  • 按词/按行读取

    std::ifstream fin("data.txt");
    std::string word;
    while (fin >> word) { /* 按空白分隔 */ }fin.clear(); fin.seekg(0);
    std::string line;
    while (std::getline(fin, line)) { /* 读取整行,不含换行符 */ }
    
  • 混合 >>getline
    使用 >> 后会留下换行符,若紧接 getline,会读入一个空行。
    解决:每次切换前调用 fin.ignore() 跳过残留的 '\n'


四、二进制文件 I/O

当读写原始字节或 POD 结构时,选用二进制模式并使用 read/write

struct Record { int id; double value; };void writeRecords(const std::vector<Record>& recs) {std::ofstream fout("rec.bin", std::ios::out|std::ios::binary);fout.write(reinterpret_cast<const char*>(recs.data()),recs.size()*sizeof(Record));
}std::vector<Record> readRecords() {std::ifstream fin("rec.bin", std::ios::in|std::ios::binary);fin.seekg(0, std::ios::end);std::size_t size = fin.tellg() / sizeof(Record);fin.seekg(0, std::ios::beg);std::vector<Record> recs(size);fin.read(reinterpret_cast<char*>(recs.data()),size*sizeof(Record));return recs;
}
  • 注意:直接写整体 vector 只对标准布局(POD)类型安全。若含指针或非平凡类型,需循环写每个字段或序列化。

五、随机访问(定位)

  • seekg / seekp:设置读/写位置

    fin.seekg(offset, std::ios::beg|std::ios::cur|std::ios::end);
    fout.seekp(...);
    
  • tellg / tellp:返回当前位置

    auto pos = fin.tellg();
    
  • 注意:文本模式下各种平台会对换行做转换,seek/tell 不保证以字节为单位精确跳转;二进制模式下则如你所见。


六、错误处理与异常

1. 状态位检查

if (!fin) { /* 打开失败或已处于错误状态 */ }
if (fin.eof()) { /* 到达末尾 */ }
if (fin.fail()) { /* 格式错误或开关失败 */ }

2. 异常模式

fin.exceptions(std::ios::failbit | std::ios::badbit);
try {int x;fin >> x;  // 失败时抛 std::ios_base::failure
} catch (const std::ios_base::failure& e) {std::cerr << "I/O 异常: " << e.what() << "\n";
}

3. 资源管理

  • 文件流析构时会自动 close(),但若需提前关闭或检测错误,可显式:

    fin.close();
    if (fin.fail()) std::cerr<<"关闭失败\n";
    

七、性能优化

  1. 同步关闭

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    

    可加速与 C 风格 I/O 的混用场景。

  2. 缓冲区大小

    • 默认缓冲区通常足够;若需高性能可自定义:重载流的 rdbuf()->pubsetbuf()
  3. 减少临时与拷贝

    • 尽量一次性 read/write 大块数据;
    • 对文本分词解析可用 std::string_viewstd::getline 配合 std::stringstream
  4. 避免频繁开关文件

    • 对同一文件的多次写入,宜在同一流对象上完成;若交替读写,用 fstream 且调用 seek/flush 而非反复构造流。

八、综合示例

#include <iostream>
#include <fstream>
#include <vector>
#include <string>struct Record { int id; double value; };int main() {// 1. 文本写入{std::ofstream log("app.log", std::ios::out|std::ios::app);if (!log) throw std::runtime_error("无法打开日志");log << "程序启动\n";}// 2. 文本读取与解析{std::ifstream fin("config.txt");if (!fin) {std::cerr<<"配置文件打开失败\n";} else {std::string line;while (std::getline(fin, line)) {// 跳过空行和注释if (line.empty() || line[0]=='#') continue;std::cout<<"配置: "<<line<<"\n";}}}// 3. 二进制读写std::vector<Record> recs = {{1,1.23},{2,4.56},{3,7.89}};{std::ofstream fout("data.bin", std::ios::out|std::ios::binary);fout.write(reinterpret_cast<const char*>(recs.data()),recs.size()*sizeof(Record));}{std::ifstream fin("data.bin", std::ios::in|std::ios::binary);fin.seekg(0, std::ios::end);size_t n = fin.tellg()/sizeof(Record);fin.seekg(0);std::vector<Record> buf(n);fin.read(reinterpret_cast<char*>(buf.data()), n*sizeof(Record));std::cout<<"读取 "<<buf.size()<<" 条记录\n";}return 0;
}

九、注意事项汇总

  1. 选择合适模式:文本 vs 二进制;是否截断或追加。
  2. 检查流状态:打开后、读写后、关闭后都应检查 fail() / bad() / eof()
  3. 混合读写:使用 std::fstream 并在切换前调用 flush() / seekg() / seekp()
  4. 异常安全:开启异常模式或自行检测,避免未捕获错误导致数据不一致。
  5. 平台差异:文本模式下换行转换、字符编码(如 Windows 的 CRLF)可能影响跨平台行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity3D仿星露谷物语开发56之保存角色位置到文件

1、目标 游戏中通过Save Game保存角色位置&#xff0c;当重启游戏后&#xff0c;通过Load Game可以恢复角色的位置。 2、Player对象操作 &#xff08;1&#xff09;组件添加 给Hierarchy下的Player组件添加Generate GUID组件。 &#xff08;2&#xff09;修改SceneSave.cs脚…

TKernel模块--杂项

TKernel模块–杂项 1.DEFINE_HARRAY1 #define DEFINE_HARRAY1(HClassName, _Array1Type_) \ class HClassName : public _Array1Type_, public Standard_Transient { \public: …

c++ typeid运算符

typeid运算符能获取类型信息。获取到的是type_info对象。type_info类型如下&#xff1a; 可以看到&#xff0c;这个类删除了拷贝构造函数以及等号操作符。有一些成员函数&#xff1a;hash_code、before、name、raw_name, 还重载了和!运算符。 测试&#xff1a; void testTyp…

第304个Vulnhub靶场演练攻略:digital world.local:FALL

digital world.local&#xff1a;FALL Vulnhub 演练 FALL (digitalworld.local: FALL) 是 Donavan 为 Vulnhub 打造的一款中型机器。这款实验室非常适合经验丰富的 CTF 玩家&#xff0c;他们希望在这类环境中检验自己的技能。那么&#xff0c;让我们开始吧&#xff0c;看看如何…

【数据库】数据库恢复技术

数据库恢复技术 实现恢复的核心是使用冗余&#xff0c;也就是根据冗余数据重建不正确数据。 事务 事务是一个数据库操作序列&#xff0c;是一个不可分割的工作单位&#xff0c;是恢复和并发的基本单位。 在关系数据库中&#xff0c;一个事务是一条或多条SQL语句&#xff0c…

switch-case判断

switch-case判断 #include <stdio.h> int main() {int type;printf("请输入你的选择&#xff1a;\n");scanf("%d",&type);getchar();switch (type){case 1:printf("你好&#xff01;");break;case 2:printf("早上好&#xff01;…

从监控到告警:Prometheus+Grafana+Alertmanager+告警通知服务全链路落地实践

文章目录 一、引言1.1 监控告警的必要性1.2 监控告警的基本原理1.2.1 指标采集与存储1.2.2 告警规则与触发机制1.2.3 多渠道通知与闭环 二、技术选型与架构设计2.1 为什么选择 Prometheus 及其生态2.1.1 Prometheus 优势分析2.1.2 Grafana 可视化能力2.1.3 Alertmanager 灵活告…

STM32 UART通信实战指南:从原理到项目落地

STM32串口通信实战指南&#xff1a;从零开始手把手教你 前言&#xff1a;为什么串口这么重要&#xff1f; 在嵌入式开发中&#xff0c;串口就像设备的"嘴巴"和"耳朵"。无论是给单片机下达指令、读取传感器数据&#xff0c;还是让两个模块"对话"…

Jmeter requests

1.Jemter元件和组件 1.1 元件和组件的概念 元件&#xff1a;多个功能相似的的组件的容器&#xff0c;类似于一个工具箱。 组件&#xff1a;实现某个特定功能的实例&#xff0c;类似于工具箱中的螺丝刀&#xff0c;十字扳手... 1.2 作用域和执行顺序 1.2.1 作用域 例子&#…

计算机视觉---GT(ground truth)

在计算机视觉&#xff08;Computer Vision, CV&#xff09;领域&#xff0c;Ground Truth&#xff08;GT&#xff0c;中文常译为“真值”或“ ground truth”&#xff09; 是指关于数据的真实标签或客观事实&#xff0c;是模型训练、评估和验证的基准。它是连接算法与现实世界的…

1-Wire 一线式总线:从原理到实战,玩转 DS18B20 温度采集

引言 在嵌入式系统中&#xff0c;通信总线是连接 CPU 与外设的桥梁。从 I2C、SPI 到 UART&#xff0c;每种总线都有其独特的应用场景。而本文要介绍的1-Wire 一线式总线&#xff0c;以其极简的硬件设计和独特的通信协议&#xff0c;在温度采集、身份识别等领域大放异彩。本文将…

基于开源AI大模型AI智能名片S2B2C商城小程序源码的销售环节数字化实现路径研究

摘要&#xff1a;在数字化浪潮下&#xff0c;企业销售环节的转型升级已成为提升竞争力的核心命题。本文基于清华大学全球产业研究院《中国企业数字化转型研究报告&#xff08;2020&#xff09;》提出的“提升销售率与利润率、打通客户数据、强化营销协同、构建全景用户画像、助…

Linux浅谈

Linux浅谈 一、什么是 Linux&#xff1f;先抛开 “内核”&#xff0c;看整体 可以把 Linux 系统 想象成一台 “组装电脑”&#xff1a; 最核心的零件是 “主板”—— 这就是 Linux 内核&#xff08;Kernel&#xff09;&#xff0c;负责管理电脑里的所有硬件&#xff08;比如 …

PostgreSQL ERROR: out of shared memory处理

使用pg_dump命令导出一个库的时候&#xff0c;报 pg_dump: error: query failed: ERROR: out of shared memory HINT: You might need to increase "max_locks_per_transaction". 从错误字面上看是超出内存大小了&#xff0c;建议增加max_locks_per_transaction参…

IoT/基于NB28-A/BC28-CNV通信模组使用AT指令连接华为云IoTDA平台(HCIP-IoT实验2)

文章目录 概述检查通信环境通信模组固件信号强度CGATT指令参数 / 啥是PS域&#xff1f;PS附着状态&#xff1a;ATCGATTPLMN 选择&#xff1a;ATCOPSCEREG指令参数 / 啥是EPS与EPC?CEREG指令参数 / 啥是URC?网络注册状态&#xff1a;ATCEREG网络附着和网络注册 AT指令接入IoTD…

红外遥控(外部中断)

目录 1.红外遥控简介 通信方式&#xff1a; 红外LED波长&#xff1a; 通信协议标准&#xff1a; 2.硬件电路 发送部分1&#xff1a; 内部元件介绍&#xff1a; 工作原理&#xff1a; 为什么要以38KHZ亮灭&#xff1f; 电路图&#xff1a; 发送部分2&#xff1a; 电…

【C#】一个简单的http服务器项目开发过程详解

这跟安装NoteJs程序运行脚本文件搭建一个简单Http服务器一样&#xff0c;相比起来&#xff0c;它的优点是可以开发的应用是免安装&#xff0c;跨平台的&#xff0c;放在移动盘上便捷的&#xff0c;这里着重讲http服务器实现的过程&#xff0c;以便自主实现特定的功能和服务。 …

WPF【11_4】WPF实战-重构与美化(MVVM 架构)

11-9 【理论】MVVM 架构 在 WPF 项目中&#xff0c;我们主要采用的是一种类似 MVC 的架构&#xff0c;叫做 MVVM。 MVVM 继承了 MVC 的理念&#xff0c;是 Model-View-ViewModel 的缩写&#xff0c;中文意思是模型、视图、视图模型。这三个词分开看我们都能看懂&#xff0c;不…

使用PowerBI个人网关定时刷新数据

使用PowerBI个人网关定时刷新数据 PowerBI desktop连接mysql&#xff0c;可以设置定时刷新数据或在PowerBI服务中手动刷新数据,步骤如下&#xff1a; 第一步&#xff1a; 下载网关。以个人网关为例&#xff0c;如图 第二步&#xff1a; 双击网关&#xff0c;点击下一步&…

深度学习驱动的超高清图修复技术——综述

Deep Learning-Driven Ultra-High-Definition Image Restoration: A Survey Liyan Wang, Weixiang Zhou, Cong Wang, Kin-Man Lam, Zhixun Su, Jinshan Pan Abstract Ultra-high-definition (UHD) image restoration​​ aims to specifically solve the problem of ​​quali…