C++fileoperationtutorial

LearningC++in fileoperation, includingfile 打开, 读取, 写入etc.operation

返回tutoriallist

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.