C 文件和流 完整笔记理论可运行代码第一部分理论知识点全面覆盖1. 核心头文件与三大文件流类文件操作必须包含的头文件三大类分别对应读、写、读写功能无需额外配置直接引入即可使用。#includeiostream#includefstream// 文件操作必备头文件#includestringusingnamespacestd;类名全称核心功能ifstreaminput file stream文件读取输入流仅用于从文件获取内容ofstreamoutput file stream文件写入输出流仅用于向文件写入内容fstreamfile stream同时支持读和写可灵活切换读写模式2. 文件打开 open()2.1 函数原型open() 是 fstream、ifstream、ofstream 的成员函数用于指定文件路径和打开模式。voidopen(constchar*fileName,ios::openmode mode);2.2 常用打开模式模式可单独使用也可通过\|组合使用核心模式如下模式标志核心说明注意事项ios::in只读模式打开文件文件必须存在否则打开失败ios::out只写模式打开文件文件不存在则自动创建存在则默认清空内容ios::app追加模式写入内容均添加到文件末尾不覆盖原有内容适合日志写入ios::ate打开文件后指针自动定位到文件末尾可读写仅改变初始指针位置ios::trunc打开文件时清空原有所有内容常与 ios::out 组合实现覆盖写入ios::binary二进制模式读写文件不转换换行符适合读取图片、视频等二进制文件2.3 常用模式组合示例// 1. 覆盖写入清空原有内容只写ofstreamfout(a.txt,ios::out|ios::trunc);// 2. 追加写入不覆盖只写ofstreamfout(log.txt,ios::app);// 3. 读写模式不清空内容fstreamfs(b.txt,ios::in|ios::out);// 4. 二进制读取ifstreamfin(data.bin,ios::in|ios::binary);2.4 打开状态判断必做文件打开可能失败路径错误、权限不足等必须判断打开状态避免后续读写报错。ifstream fin;fin.open(test.txt,ios::in);if(!fin.is_open())// 或者 if (!fin){cout文件打开失败endl;return-1;// 终止程序避免后续错误}3. 文件关闭 close()文件使用完毕后必须关闭核心作用是释放系统资源、刷新缓冲区确保写入内容真正保存到文件。语法fin\.close\(\);、fout\.close\(\);、fs\.close\(\);补充局部流对象函数内定义生命周期结束时会自动调用 close()但建议手动关闭养成良好习惯。4. 文本文件读写操作文本文件是最常用的文件类型读写语法与 cout、cin 高度一致易上手。4.1 文本写入ofstream使用\lt;\lt;运算符与 cout 用法完全相同可写入字符串、数字等任意类型。4.2 文本读取ifstream有两种核心方式根据需求选择方式1\gt;\gt;运算符自动忽略空格、Tab、换行符按“单词”分割读取。方式2getline() 函数读取一整行内容保留空格适合读取带空格的字符串。4.3 遍历文件重点避坑使用 eof() 判断文件末尾时存在“滞后性”会导致最后一行内容被重复读取推荐使用标准正确写法。错误写法while (!fin.eof()) { ... }正确写法while (fin gt;gt; 变量) { ... } 或 while (fin.getline(...)) { ... }5. 二进制文件读写二进制文件用于存储非文本数据如图片、音频、结构体等必须添加ios::binary模式避免换行符自动转换。写入使用 write() 函数传入内存地址和数据大小。读取使用 read() 函数传入接收数据的内存地址和数据大小。6. 文件指针与随机访问文件指针用于定位读写位置支持“随机读写”不按顺序直接跳转到指定位置核心函数分两类6.1 核心函数读指针seekg()移动读指针、tellg()获取当前读指针位置写指针seekp()移动写指针、tellp()获取当前写指针位置6.2 基准位置第二个参数ios::beg以文件开头为基准默认值ios::cur以当前指针位置为基准ios::end以文件末尾为基准6.3 常用示例获取文件大小将读指针移动到文件末尾通过 tellg() 获取指针位置即为文件字节大小。7. 文件流状态标志错误处理用于判断文件读写过程中的错误状态核心标志如下fin.good()返回 true表示流状态正常无错误fin.fail()返回 true表示打开失败、读取格式错误如用 int 接收字符串fin.bad()返回 true表示严重 IO 错误如硬件故障fin.eof()返回 true表示到达文件末尾fin.clear()清空错误标志恢复流的读写功能8. 关键细节补充避坑重点endl 与 \n 的区别endl 换行 强制刷新缓冲区\n 仅换行不刷新IO 效率更高频繁写入建议用 \n。文本模式与二进制模式Windows 系统中文本模式会自动转换 \n lt;gt; \r\n换行符二进制模式不转换。cin.ignore() 的作用混合使用 cin gt;gt; 和 getline() 时cin gt;gt; 会残留换行符导致 getline() 空读需用 cin.ignore(1024, #39;\n#39;) 清空。RAII 特性fstream 是 RAII 对象离开作用域如函数结束会自动析构析构时会调用 close()无需过度担心忘记关闭。9. 极简背诵总结考点重点三大流类ifstream读、ofstream写、fstream读写。二进制文件必加模式ios::binary否则会出现读写异常。读取方式按单词用 gt;gt;按行用 getline()整块二进制用 read/write。文件指针读指针 gseekg/tellg写指针 pseekp/tellp。遍历文件禁止用 while(!fin.eof())推荐 while(fin gt;gt; 变量)。第二部分可运行代码合集直接复制编译所有代码均已测试无语法错误复制到编译器即可运行对应上述理论知识点方便边学边练。1. 通用头文件模板所有代码可复用#includeiostream#includefstream#includestring#includecstringusingnamespacestd;2. 文本文件写入ofstream// 文本写入覆盖原有内容intmain(){ofstreamfout(write.txt);// 默认 ios::out | ios::truncfoutC 文件流测试endl;fout666 3.14endl;fout带空格的字符串 测试endl;fout.close();return0;}3. 文本文件读取 - 方式1gt;gt; 按单词读取// 按空格/换行分割读取自动忽略空白字符intmain(){ifstreamfin(write.txt);if(!fin.is_open()){cout文件打开失败endl;return-1;}string s;doubled;// 正确遍历方式while(finsd){cout读取内容s | dendl;}fin.close();return0;}4. 文本文件读取 - 方式2getline 按行读取// 整行读取保留空格适合读取带空格的内容intmain(){ifstreamfin(write.txt);if(!fin.is_open()){cout文件打开失败endl;return-1;}charbuf[1024];// 缓冲区可根据需求调整大小// 正确遍历方式while(fin.getline(buf,sizeof(buf))){cout一行内容bufendl;}fin.close();return0;}5. 文件打开 合法性判断必写模板// 通用打开判断模板适用于所有文件类型intmain(){ifstreamfin(test.txt,ios::in);// 两种判断方式均可if(!fin.is_open())// 方式1判断是否打开成功// if (!fin) // 方式2简化判断流对象为空则打开失败{cout文件打开失败可能路径错误或文件不存在endl;return-1;}cout文件打开成功可进行读写操作endl;fin.close();return0;}6. 追加写入文件ios::app 模式// 追加写入不覆盖原有内容添加到文件末尾intmain(){ofstreamfout(write.txt,ios::app);if(!fout.is_open()){cout文件打开失败endl;return-1;}fout 追加的内容 endl;fout追加测试123456endl;fout.close();cout追加写入完成endl;return0;}7. fstream 读写一体同时读写// 读写一体先写入内容再读取并输出intmain(){// ios::in | ios::out | ios::trunc读写清空原有内容fstreamfs(rw.txt,ios::in|ios::out|ios::trunc);if(!fs.is_open()){cout文件打开失败endl;return-1;}// 1. 写入内容fsfstream 读写一体测试endl;fs测试数据100 200 300endl;// 2. 移动读指针到文件开头否则读取不到内容fs.seekg(0,ios::beg);// 3. 读取内容并输出string res;while(getline(fs,res)){cout读取到resendl;}fs.close();return0;}8. 二进制写入write 结构体// 二进制写入结构体适合存储复杂数据如用户信息structPerson{charname[20];// 姓名intage;// 年龄doublescore;// 分数};intmain(){ofstreamfout(data.bin,ios::out|ios::binary);if(!fout.is_open()){cout文件打开失败endl;return-1;}Person p1{李四,22,95.5};Person p2{张三,21,88.0};// 写入(char*)p 转换为字符指针sizeof(Person) 是数据大小fout.write((char*)p1,sizeof(Person));fout.write((char*)p2,sizeof(Person));fout.close();cout二进制写入完成endl;return0;}9. 二进制读取read 结构体// 二进制读取结构体与上面的写入代码对应structPerson{charname[20];intage;doublescore;};intmain(){ifstreamfin(data.bin,ios::in|ios::binary);if(!fin.is_open()){cout文件打开失败endl;return-1;}Person p;// 读取第一个结构体fin.read((char*)p,sizeof(Person));cout姓名p.name 年龄p.age 分数p.scoreendl;// 读取第二个结构体fin.read((char*)p,sizeof(Person));cout姓名p.name 年龄p.age 分数p.scoreendl;fin.close();return0;}10. 文件指针 - 随机访问 获取文件大小// 移动文件指针获取文件大小实现随机读写intmain(){fstreamfs(write.txt,ios::in|ios::out);if(!fs.is_open()){cout文件打开失败endl;return-1;}// 1. 定位读指针到文件末尾获取文件大小字节数fs.seekg(0,ios::end);longlongfileSizefs.tellg();cout文件大小fileSize 字节endl;// 2. 移动读指针到文件开头fs.seekg(0,ios::beg);// 3. 移动读指针到第 10 字节从开头计数fs.seekg(10,ios::beg);charbuf[1024];fs.getline(buf,sizeof(buf));cout从第10字节开始读取bufendl;// 4. 移动写指针到文件末尾追加写入fs.seekp(0,ios::end);fs随机写入测试endl;fs.close();return0;}11. 文件状态位 - 错误处理// 检测文件流状态处理打开失败、读取错误等情况intmain(){ifstreamfin(none.txt);// 不存在的文件// 判断打开失败if(fin.fail()){cout错误文件读取失败 / 文件不存在endl;}// 清空错误标志恢复流状态可重新打开其他文件fin.clear();// 重新打开正确文件fin.open(write.txt);if(fin.good()){cout流状态正常文件打开成功endl;}// 判断是否到达文件末尾fin.seekg(0,ios::end);if(fin.eof()){cout已到达文件末尾endl;}fin.close();return0;}12. 完整文件复制工具常用实用工具// 复制 src.txt 到 dest.txt支持文本、二进制文件通用intmain(){// 打开源文件读和目标文件写二进制模式ifstreamfin(src.txt,ios::in|ios::binary);ofstreamfout(dest.txt,ios::out|ios::binary);if(!fin.is_open()||!fout.is_open()){cout文件打开失败endl;return-1;}// 逐字符复制适配所有文件类型charch;while(fin.get(ch)){fout.put(ch);}cout文件复制完成endl;fin.close();fout.close();return0;}13. 避坑示例eof() 错误写法 vs 正确写法#includeiostream#includefstream#includestringusingnamespacestd;// ❌ 错误写法eof() 滞后会重复读取最后一行voidwrongRead(){ifstreamfin(write.txt);string s;cout错误写法读取结果endl;while(!fin.eof()){fins;couts ;}fin.close();coutendl------------------------endl;}// ✅ 正确写法判断读取是否成功避免重复voidrightRead(){ifstreamfin(write.txt);string s;cout正确写法读取结果endl;while(fins){couts ;}fin.close();}intmain(){wrongRead();rightRead();return0;}14. cin.ignore() 避坑示例混合 cingt;gt; 和 getline// 解决 cin 残留换行符导致 getline 空读的问题intmain(){intage;string name;cout请输入年龄;cinage;// 清空 cin 残留的换行符否则 getline 会读取到空行cin.ignore(1024,\n);cout请输入姓名可带空格;getline(cin,name);cout你输入的年龄age姓名nameendl;return0;}