C++ | 高级教程 | 文件和流

👻 概念

文件流输出使用标准库 fstream,定义三个新的数据类型:

数据类型 描述
ofstream 输出文件流,用于创建文件并向文件写入信息。
ifstream 输入文件流,用于从文件读取信息。
fstream 文件流,且同时具有 ofstream 和 ifstream 两种功能,意味着可以创建文件,写入信息,读取信息

👻 准备工作

  • 使用文件流需要包含 <iostream> 和 <fstream> 头文件
c++ 复制代码
#include <fstream>
#include <iostream>

👻 打开文件

👾语法格式

使用 open() 函数打开文件,是 fstream、ifstream 、ofstream 对象的成员

c++ 复制代码
void open(const char *filename, ios::openmode mode);
  • 参数 filename ------ 打开文件的名称和位置

  • 参数 mode ------ 文件被打开的模式

    模式标志 描述
    ios::app 追加模式,所有写入都追加到文件末尾
    ios::ate 文件打开后定位到文件末尾
    ios::in 打开文件用于读取
    ios::out 打开文件用于写入
    ios::trunc 如果该文件已经存在,其内容将在打开文件之前被截断,即把文件长度设为 0

👾示例代码

  • 示例1 :以写入模式 打开文件,并希望截断文件,以防文件已存在

    c++ 复制代码
    ofstream outfile;
    outfile.open("file.dat", ios::out | ios::trunc );
  • 示例2 :打开一个文件用于读写

    c++ 复制代码
    ifstream infile;
    infile.open("file.dat", ios::out | ios::in );

👻 关闭文件

👾语法格式

使用 close() 函数打开文件,是 fstream、ifstream 、ofstream 对象的成员。

程序终止时,会自动关闭刷新所有流,释放所有分配的内存,并关闭所有打开的文件

c++ 复制代码
void close();

👾示例代码

c++ 复制代码
outfile.close();

👻 写入文件

👾语法格式

使用流插入运算符 << 向文件写入信息,使用的是 ofstream 或 fstream 对象

c++ 复制代码
ofstream << data;

👻 读取文件

👾语法格式

使用流提取运算符 >> 向文件写入信息,使用的是 ifstream 或 fstream 对象

c++ 复制代码
ifstream >> data;

👻 文件位置指针

👾语法格式

使用 istream 的 seekg(seek get)和关于 ostream 的 seekp(seek put)重新定位文件位置指针。

复制代码
istream& seekg(streampos pos);
ostream& seekp(streampos pos);
  • 参数 pos ------ 直接定位到流中的绝对位置,其中 streampos 是一个表示流位置的类型

    c++ 复制代码
    istream& seekg(streamoff off, ios::seekdir dir);
    ostream& seekp(streamoff off, ios::seekdir dir);
  • 参数 off ------ 偏移量(正数/负数)

  • 参数 dir ------ 定位方向

    模式标志 描述
    ios::beg 从流的开头开始计算偏移量
    ios::cur 从当前读取位置开始计算偏移量
    ios::end 从流的末尾开始计算偏移量

👾示例代码

文件位置指针是一个整数值,指定了从文件的起始位置到指针所在位置的字节数。

c++ 复制代码
// 定位到 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);

👻 综合实例

c++ 复制代码
char data[100];

// 写模式打开文件
ofstream outfile;
outfile.open("test.txt");
cout << "Writing to the file" << endl;

// 写入数据
cout << "Enter your name: ";
cin.getline(data, 100);
outfile << data << endl;

cout << "Enter your age: ";
cin >> data;
cin.ignore();
outfile << data << endl;

// 关闭文件
outfile.close();  
c++ 复制代码
char data[100];

// 读模式打开文件
ifstream infile;
infile.open("test.txt");
cout << "Reading from the file" << endl;
	
// 读取数据
infile >> data;
cout << data << endl;
infile >> data;
cout << data << endl;

// 关闭文件
infile.close();  

cin.getline( ) 与 cin >> 区别

cin.getline( ) cin >>
读取方式 按行读取 ------ 读取输入流中的字符 ,直到遇到换行符 \n 为止,并将换行符之前的字符存储到目标字符串中。 逐个单词读取 ------ 读取输入流中的下一个非空白字符 ,直到遇到空白字符(如空格 、制表符 \t 、换行符 \n)为止
前导空白字符 从当前输入流的位置开始读取,不跳过前导空白字符 跳过输入流前面所有前导空白字符
存储换行符 读取到换行符为止,存储换行符之前的字符,并自动处理换行符 不会读取换行符
清理缓冲区 自动处理换行符,不需要额外清理缓冲区 手动清理输入缓冲区中的换行符,如使用 cin.ignore()
用途 读取整行文本 读取单个单词或数字
理解 输入 ABCDEFG\n ,读取 ABCDEFG\n,并自动处理换行符,输入变量值为 ABCDEFG,缓冲区为空 输入 ABCDEFG\n ,读取 ABCDEFG,输入变量值为 ABCDEFG,缓冲区为 \n,为避免影响后面的输入,需要手动清理

cin.ignore( ) 的作用

主要用于清除缓冲区中的换行符,以避免影响后续的输入操作,即手动清理缓冲区。对代码:

cpp 复制代码
cout << "Enter your name: ";
cin.getline(data, 100); // 读取姓名
outfile << data << endl;

cout << "Enter your age: ";
cin >> data;  // 读取年龄
cin.ignore();  // 清除缓冲区中的换行符
outfile << data << endl;

cout << "Enter your address: ";
cin.getline(data, 100);  // 读取地址
outfile << data << endl;

如果移除 cin.ignore() 语句,

  • 缓冲区中的换行符 \n 会被 cin.getline() 读取,导致 data 被赋值为空字符串,该输入被跳过。

  • 文件中写入的内容会变成:

    John Doe
    25


如果使用了 cin.ignore(),

  • 缓冲区中的换行符会被清除,cin.getline() 会正确读取用户输入的地址。

  • 文件中写入的内容会是:

    John Doe
    25
    Your Address

相关推荐
局部有解5 小时前
Leetcode - 42 接雨水(一维)
数据结构·c++·算法·leetcode
fpcc5 小时前
c++20新功能—std::osyncstream
c++·c++20
H.莓飛5 小时前
【C++】模板初阶
linux·开发语言·c++·visual studio
十五年专注C++开发5 小时前
基于Asio2实现http服务器的实践总结(二)
服务器·c++·http·asio2
技术不好的崎鸣同学5 小时前
第七章:模块踩踏以覆写导出函数绕过CFG
c++·windows·安全·系统安全
miofly5 小时前
GitHub 今日推荐|ps2-web-recomp:浏览器里跑 PS2 游戏的静态重编译方案
c++·开源·github
沫璃染墨5 小时前
从零入门计算机网络系列(五):UDP套接字编程实战——从核心API到客户端与服务器通信
linux·网络·c++·vscode·网络协议·udp
hetao17338376 小时前
联盟场-提高组-R4 & ZYZSC-S-Round 7
c++·算法
hetao17338376 小时前
联盟场-提高组-R2 & ZYZSC-S-Round 5
c++·算法
X北辰北7 小时前
C++ 进阶第二阶段总结|STL容器全家桶、迭代器失效、STL算法、序列化入门(工程必备)
开发语言·c++·算法