1. fileoperationoverview
1.1 what is fileoperation?
fileoperation is 指程序 and out 部file之间 交互, including读取file in 容, 写入data to file, modifyfileetc.operation.
in C++in, fileoperation主要throughfile流 (file stream) 来implementation, file流 is a特殊 流object, 用于processingfile 输入 and 输出.
1.2 C++in file流class
C++标准libraryproviding了以 under file流class:
- ofstream: 输出file流, 用于creation and 写入file
- ifstream: 输入file流, 用于读取file
- fstream: file流, 同时support输入 and 输出operation
这些class都定义 in 头file<fstream>in.
2. file 打开 and 关闭
2.1 file 打开
in forfileoperation之 before , 需要先打开file. 可以through以 under 方式打开file:
2.1.1 usingconstructfunction打开file
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// creation输出file流并打开file
ofstream outFile("example.txt");
if (outFile.is_open()) {
cout << "file打开成功" << endl;
// 写入operation...
outFile.close(); // 关闭file
} else {
cout << "file打开失败" << endl;
}
return 0;
}
2.1.2 usingopen()method打开file
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// creation输出file流
ofstream outFile;
// 打开file
outFile.open("example.txt");
if (outFile.is_open()) {
cout << "file打开成功" << endl;
// 写入operation...
outFile.close(); // 关闭file
} else {
cout << "file打开失败" << endl;
}
return 0;
}
2.2 file打开模式
打开file时, 可以指定file 打开模式:
- ios::in: 以输入模式打开file (用于ifstream)
- ios::out: 以输出模式打开file (用于ofstream)
- ios::app: 以追加模式打开file, 写入 data会添加 to file末尾
- ios::trunc: such as果file已存 in , 将其截断 for 零 long 度
- ios::binary: 以二进制模式打开file
- ios::ate: 打开file after 立即定位 to file末尾
可以using位运算符|组合 many 个模式:
// 以写入模式打开file, such as果file存 in 则截断
ofstream outFile("example.txt", ios::out | ios::trunc);
// 以追加模式打开file
ofstream appendFile("example.txt", ios::out | ios::app);
// 以读写模式打开file
fstream file("example.txt", ios::in | ios::out);
2.3 file 关闭
fileoperationcompletion after , 应该usingclose()method关闭file:
ofstream outFile("example.txt");
// 写入operation...
outFile.close(); // 关闭file
关闭file important 性:
- 释放fileresource, 避免resource泄漏
- 确保所 has data都被写入file
- 允许other程序访问该file
3. file 写入operation
3.1 usingofstream写入file
可以using<<运算符向file写入data:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// creation输出file流
ofstream outFile("example.txt");
if (outFile.is_open()) {
// 写入string
outFile << "Hello, World!" << endl;
// 写入number
int age = 25;
outFile << "年龄: " << age << endl;
// 写入浮点数
double salary = 5000.50;
outFile << "工资: " << salary << endl;
cout << "data写入成功" << endl;
outFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
3.2 usingfstream写入file
也可以usingfstreamclassforfile写入operation:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// creationfile流, 以读写模式打开
fstream file("example.txt", ios::out | ios::trunc);
if (file.is_open()) {
file << "usingfstream写入file" << endl;
file << "这 is 第二行" << endl;
cout << "data写入成功" << endl;
file.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
4. file 读取operation
4.1 usingifstream读取file
可以using>>运算符 from file读取data:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
// creation输入file流
ifstream inFile("example.txt");
if (inFile.is_open()) {
string line;
cout << "file in 容: " << endl;
// 逐行读取file in 容
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
4.2 using>>运算符读取file
>>运算符会自动跳过空白字符 (空格, 制表符, 换行符etc.) :
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
// creation输入file流
ifstream inFile("example.txt");
if (inFile.is_open()) {
string word;
cout << "file in 容 (单词) : " << endl;
// 逐个单词读取
while (inFile >> word) {
cout << word << endl;
}
inFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
4.3 checkfile is 否结束
可以usingeof()methodcheckfile is 否读取结束:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
// creation输入file流
ifstream inFile("example.txt");
if (inFile.is_open()) {
string line;
cout << "file in 容: " << endl;
// 读取file直 to 结束
while (!inFile.eof()) {
getline(inFile, line);
cout << line << endl;
}
inFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
5. file 定位operation
5.1 file指针
file流object in 部maintenance着一个file指针, 用于指示当 before 读写位置.
- for 于输入流, 指针指向 under 次读取 位置
- for 于输出流, 指针指向 under 次写入 位置
5.2 定位method
C++providing了以 under method来定位file指针:
- tellg(): 获取输入流 当 before 位置
- seekg(): 设置输入流 位置
- tellp(): 获取输出流 当 before 位置
- seekp(): 设置输出流 位置
5.2.1 file指针 定位example
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
// 写入file
ofstream outFile("example.txt");
if (outFile.is_open()) {
outFile << "Hello, World!" << endl;
outFile << "This is a test." << endl;
outFile.close();
}
// 读取file并定位
ifstream inFile("example.txt");
if (inFile.is_open()) {
string line;
// 读取第一行
getline(inFile, line);
cout << "第一行: " << line << endl;
// 获取当 before 位置
streampos pos = inFile.tellg();
cout << "当 before 位置: " << pos << endl;
// 读取第二行
getline(inFile, line);
cout << "第二行: " << line << endl;
// 定位 to file开头
inFile.seekg(0, ios::beg);
cout << "回 to file开头" << endl;
// 再次读取第一行
getline(inFile, line);
cout << "再次读取第一行: " << line << endl;
inFile.close();
}
return 0;
}
5.3 定位模式
seekg() and seekp()method 第二个parameter可以指定定位模式:
- ios::beg: from file开头开始计算偏移量
- ios::cur: from 当 before 位置开始计算偏移量
- ios::end: from file末尾开始计算偏移量
// 定位 to file开头 inFile.seekg(0, ios::beg); // from 当 before 位置向 after move10个字节 inFile.seekg(10, ios::cur); // 定位 to file末尾 before 5个字节 inFile.seekg(-5, ios::end);
6. 二进制fileoperation
6.1 二进制file 打开
以二进制模式打开file, 需要指定ios::binary模式:
// 以二进制模式写入file
ofstream outFile("data.bin", ios::out | ios::binary);
// 以二进制模式读取file
ifstream inFile("data.bin", ios::in | ios::binary);
6.2 二进制file 写入
usingwrite()method写入二进制data:
#include <fstream>
#include <iostream>
using namespace std;
struct Student {
char name[50];
int age;
double score;
};
int main() {
// creation学生object
Student s1 = {"张三", 18, 95.5};
Student s2 = {"李四", 19, 88.0};
// 以二进制模式写入file
ofstream outFile("students.bin", ios::out | ios::binary);
if (outFile.is_open()) {
// 写入学生data
outFile.write(reinterpret_cast(&s1), sizeof(s1));
outFile.write(reinterpret_cast(&s2), sizeof(s2));
cout << "二进制data写入成功" << endl;
outFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
6.3 二进制file 读取
usingread()method读取二进制data:
#include <fstream>
#include <iostream>
using namespace std;
struct Student {
char name[50];
int age;
double score;
};
int main() {
// 以二进制模式读取file
ifstream inFile("students.bin", ios::in | ios::binary);
if (inFile.is_open()) {
Student s;
// 读取第一个学生data
inFile.read(reinterpret_cast(&s), sizeof(s));
cout << "学生1: " << endl;
cout << "姓名: " << s.name << endl;
cout << "年龄: " << s.age << endl;
cout << "成绩: " << s.score << endl;
// 读取第二个学生data
inFile.read(reinterpret_cast(&s), sizeof(s));
cout << "\n学生2: " << endl;
cout << "姓名: " << s.name << endl;
cout << "年龄: " << s.age << endl;
cout << "成绩: " << s.score << endl;
inFile.close();
} else {
cout << "file打开失败" << endl;
}
return 0;
}
7. fileoperation errorprocessing
7.1 checkfile打开 is 否成功
in forfileoperation之 before , 应该checkfile is 否成功打开:
ifstream inFile("example.txt");
if (!inFile) {
cout << "file打开失败" << endl;
return 1;
}
// or 者usingis_open()method
if (!inFile.is_open()) {
cout << "file打开失败" << endl;
return 1;
}
7.2 check读取 is 否成功
in 读取file时, 应该check读取operation is 否成功:
ifstream inFile("example.txt");
if (inFile.is_open()) {
int value;
if (inFile >> value) {
cout << "读取成功: " << value << endl;
} else {
cout << "读取失败" << endl;
}
inFile.close();
}
7.3 清除errorstatus
当fileoperation发生error时, 可以usingclear()method清除errorstatus:
ifstream inFile("example.txt");
if (inFile.is_open()) {
int value;
// 尝试读取
while (inFile >> value) {
cout << value << endl;
}
// check is 否 to 达file末尾
if (inFile.eof()) {
cout << "已 to 达file末尾" << endl;
} else {
cout << "读取过程in发生error" << endl;
}
// 清除errorstatus
inFile.clear();
// 可以继续forotheroperation
inFile.close();
}
实践case: 学生成绩managementsystem
writing一个C++程序, implementation一个 simple 学生成绩managementsystem, usingfilestore学生data.
requirementsanalysis
- creation一个
Studentstructure体, package含姓名, 学号, 成绩etc.information. - implementation添加学生functions, 将学生data写入file.
- implementation查看所 has 学生functions, from filein读取并显示学生data.
- implementation按学号find学生functions.
referencecode
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
struct Student {
char name[50];
char id[20];
double score;
};
// 添加学生void addStudent() {
ofstream outFile("students.txt", ios::out | ios::app);
if (outFile.is_open()) {
Student s;
cout << "输入学生姓名: ";
cin.ignore(); // ignore之 before 换行符
cin.getline(s.name, 50);
cout << "输入学生学号: ";
cin.getline(s.id, 20);
cout << "输入学生成绩: ";
cin >> s.score;
// 写入file
outFile << s.name << " " << s.id << " " << s.score << endl;
cout << "学生添加成功!" << endl;
outFile.close();
} else {
cout << "file打开失败" << endl;
}
}
// 查看所 has 学生
void showAllStudents() {
ifstream inFile("students.txt");
if (inFile.is_open()) {
Student s;
string line;
cout << "所 has 学生information: " << endl;
cout << "----------------------------------" << endl;
while (inFile >> s.name >> s.id >> s.score) {
cout << "姓名: " << s.name << ", 学号: " << s.id << ", 成绩: " << s.score << endl;
}
cout << "----------------------------------" << endl;
inFile.close();
} else {
cout << "file打开失败" << endl;
}
}
// 按学号find学生
void findStudentById() {
ifstream inFile("students.txt");
if (inFile.is_open()) {
Student s;
string targetId;
cout << "输入要find 学号: ";
cin >> targetId;
bool found = false;
while (inFile >> s.name >> s.id >> s.score) {
if (s.id == targetId) {
cout << "找 to 学生: " << endl;
cout << "姓名: " << s.name << ", 学号: " << s.id << ", 成绩: " << s.score << endl;
found = true;
break;
}
}
if (!found) {
cout << "未找 to 该学号 学生" << endl;
}
inFile.close();
} else {
cout << "file打开失败" << endl;
}
}
int main() {
int choice;
do {
cout << "\n学生成绩managementsystem" << endl;
cout << "1. 添加学生" << endl;
cout << "2. 查看所 has 学生" << endl;
cout << "3. 按学号find学生" << endl;
cout << "0. 退出" << endl;
cout << "请选择operation: ";
cin >> choice;
switch (choice) {
case 1:
addStudent();
break;
case 2:
showAllStudents();
break;
case 3:
findStudentById();
break;
case 0:
cout << "退出system" << endl;
break;
default:
cout << "无效选择" << endl;
break;
}
} while (choice != 0);
return 0;
}
run结果
学生成绩managementsystem 1. 添加学生 2. 查看所 has 学生 3. 按学号find学生 0. 退出 请选择operation: 1 输入学生姓名: 张三 输入学生学号: 2023001 输入学生成绩: 95 学生添加成功! 学生成绩managementsystem 1. 添加学生 2. 查看所 has 学生 3. 按学号find学生 0. 退出 请选择operation: 1 输入学生姓名: 李四 输入学生学号: 2023002 输入学生成绩: 88 学生添加成功! 学生成绩managementsystem 1. 添加学生 2. 查看所 has 学生 3. 按学号find学生 0. 退出 请选择operation: 2 所 has 学生information: ---------------------------------- 姓名: 张三, 学号: 2023001, 成绩: 95 姓名: 李四, 学号: 2023002, 成绩: 88 ---------------------------------- 学生成绩managementsystem 1. 添加学生 2. 查看所 has 学生 3. 按学号find学生 0. 退出 请选择operation: 3 输入要find 学号: 2023001 找 to 学生: 姓名: 张三, 学号: 2023001, 成绩: 95 学生成绩managementsystem 1. 添加学生 2. 查看所 has 学生 3. 按学号find学生 0. 退出 请选择operation: 0 退出system
互动练习
练习1: writing一个C++程序, 将user输入 文本保存 to filein, 然 after 再 from filein读取并显示出来.
练习2: writing一个C++程序, statisticsfilein 单词数量.
练习3: modify实践casein 学生成绩managementsystem, 添加modify学生成绩 and delete学生 functions.