1.结构体应用
登录以参加训练计划
C++ 结构体与文件操作详解 - CSP-J 核心知识点
面向10-14岁学生,结合CSP-J考纲整理的结构体与文件操作知识
目录
- 结构体基础
- 结构体数组
- 结构体与函数
- 文件基础操作
- 结构体与文件结合
- 综合应用
1. 结构体基础
结构体的概念
结构体是自定义的数据类型,可以包含多个不同类型的成员变量
#include <iostream>
#include <string>
using namespace std;
// 定义学生结构体
struct Student {
string name; // 姓名
int age; // 年龄
double score; // 成绩
char gender; // 性别
}; // 注意分号不能少
int main() {
// 创建结构体变量
Student stu1;
// 访问成员并赋值
stu1.name = "Alice";
stu1.age = 12;
stu1.score = 95.5;
stu1.gender = 'F';
// 输出结构体信息
cout << "姓名: " << stu1.name << endl;
cout << "年龄: " << stu1.age << endl;
cout << "成绩: " << stu1.score << endl;
cout << "性别: " << stu1.gender << endl;
// 初始化结构体
Student stu2 = {"Bob", 13, 88.0, 'M'};
return 0;
}
结构体嵌套
struct Date {
int year;
int month;
int day;
};
struct Student {
string name;
Date birthday; // 嵌套结构体
};
int main() {
Student s;
s.name = "Tom";
s.birthday.year = 2010;
s.birthday.month = 5;
s.birthday.day = 15;
cout << s.name << "的生日是: "
<< s.birthday.year << "-"
<< s.birthday.month << "-"
<< s.birthday.day << endl;
return 0;
}
2. 结构体数组
定义与使用
#include <iostream>
using namespace std;
struct Student {
string name;
int score;
};
int main() {
// 创建结构体数组
Student class1[3] = {
{"Alice", 90},
{"Bob", 85},
{"Cindy", 95}
};
// 遍历结构体数组
for (int i = 0; i < 3; i++) {
cout << class1[i].name << ": " << class1[i].score << endl;
}
// 修改结构体数组元素
class1[1].score = 88;
return 0;
}
应用:学生成绩排序
#include <iostream>
#include <algorithm> // sort函数
using namespace std;
struct Student {
string name;
int score;
};
// 比较函数,按成绩降序
bool cmp(Student a, Student b) {
return a.score > b.score;
}
int main() {
Student stu[5] = {
{"Alice", 90},
{"Bob", 85},
{"Cindy", 95},
{"David", 78},
{"Eva", 92}
};
// 排序
sort(stu, stu+5, cmp);
// 输出排序结果
cout << "成绩排名:" << endl;
for (int i = 0; i < 5; i++) {
cout << i+1 << ". " << stu[i].name << ": " << stu[i].score << endl;
}
return 0;
}
3. 结构体与函数
结构体作为函数参数
#include <iostream>
using namespace std;
struct Point {
int x;
int y;
};
// 按值传递
void printPoint(Point p) {
cout << "(" << p.x << ", " << p.y << ")" << endl;
}
// 按引用传递(避免复制)
void movePoint(Point &p, int dx, int dy) {
p.x += dx;
p.y += dy;
}
int main() {
Point p1 = {3, 4};
printPoint(p1); // (3,4)
movePoint(p1, 2, 3);
printPoint(p1); // (5,7)
return 0;
}
结构体作为函数返回值
Point createPoint(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
int main() {
Point p2 = createPoint(10, 20);
printPoint(p2); // (10,20)
return 0;
}
4. 文件基础操作
文件操作步骤
- 包含头文件:
<fstream>
- 创建文件流对象
- 打开文件
- 读写操作
- 关闭文件
文件读写示例
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// 写文件
ofstream outFile("data.txt"); // 打开文件用于写
if (!outFile) {
cerr << "打开文件失败!" << endl;
return 1;
}
outFile << "Hello, File!" << endl;
outFile << 123 << " " << 3.14 << endl;
outFile.close();
// 读文件
ifstream inFile("data.txt");
if (!inFile) {
cerr << "打开文件失败!" << endl;
return 1;
}
string line;
getline(inFile, line); // 读取一行
cout << line << endl;
int a;
double b;
inFile >> a >> b; // 读取整数和浮点数
cout << a << " " << b << endl;
inFile.close();
return 0;
}
文件打开模式
模式标志 | 描述 |
---|---|
ios::in | 读取 |
ios::out | 写入(覆盖) |
ios::app | 追加 |
ios::binary | 二进制模式 |
// 追加写入
ofstream outFile("log.txt", ios::app);
outFile << "新的日志" << endl;
outFile.close();
5. 结构体与文件结合
结构体数据写入文件
#include <iostream>
#include <fstream>
using namespace std;
struct Student {
string name;
int age;
double score;
};
int main() {
Student stu[] = {
{"Alice", 12, 90.5},
{"Bob", 13, 85.0},
{"Cindy", 12, 95.5}
};
// 写入文件
ofstream outFile("students.dat", ios::binary); // 二进制模式
if (!outFile) {
cerr << "打开文件失败" << endl;
return 1;
}
// 写入结构体数组
outFile.write((char*)stu, sizeof(stu));
outFile.close();
return 0;
}
从文件读取结构体数据
int main() {
Student stu[3];
ifstream inFile("students.dat", ios::binary);
if (!inFile) {
cerr << "打开文件失败" << endl;
return 1;
}
// 读取结构体数组
inFile.read((char*)stu, sizeof(stu));
inFile.close();
// 显示读取的数据
for (int i = 0; i < 3; i++) {
cout << "姓名: " << stu[i].name
<< " 年龄: " << stu[i].age
<< " 成绩: " << stu[i].score << endl;
}
return 0;
}
文本格式读写结构体
// 写入文本格式
ofstream outText("students.txt");
for (int i = 0; i < 3; i++) {
outText << stu[i].name << " "
<< stu[i].age << " "
<< stu[i].score << endl;
}
outText.close();
// 读取文本格式
ifstream inText("students.txt");
Student s;
while (inText >> s.name >> s.age >> s.score) {
cout << s.name << " " << s.age << " " << s.score << endl;
}
inText.close();
6. 综合应用
学生成绩管理系统
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
struct Student {
string name;
int id;
double score;
};
// 添加学生
void addStudent(vector<Student> &students) {
Student s;
cout << "输入姓名: ";
cin >> s.name;
cout << "输入学号: ";
cin >> s.id;
cout << "输入成绩: ";
cin >> s.score;
students.push_back(s);
}
// 显示所有学生
void showStudents(const vector<Student> &students) {
for (const Student &s : students) {
cout << s.name << "\t"
<< s.id << "\t"
<< s.score << endl;
}
}
// 保存到文件
void saveToFile(const vector<Student> &students, string filename) {
ofstream outFile(filename);
for (const Student &s : students) {
outFile << s.name << " "
<< s.id << " "
<< s.score << endl;
}
outFile.close();
}
// 从文件加载
void loadFromFile(vector<Student> &students, string filename) {
ifstream inFile(filename);
if (!inFile) {
cerr << "文件不存在" << endl;
return;
}
students.clear();
Student s;
while (inFile >> s.name >> s.id >> s.score) {
students.push_back(s);
}
inFile.close();
}
int main() {
vector<Student> students;
int choice;
do {
cout << "\n1. 添加学生\n"
<< "2. 显示学生\n"
<< "3. 保存到文件\n"
<< "4. 从文件加载\n"
<< "0. 退出\n"
<< "请选择: ";
cin >> choice;
switch (choice) {
case 1: addStudent(students); break;
case 2: showStudents(students); break;
case 3: saveToFile(students, "students.txt"); break;
case 4: loadFromFile(students, "students.txt"); break;
}
} while (choice != 0);
return 0;
}
文件加密系统
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void encryptFile(string inputFile, string outputFile, int key) {
ifstream in(inputFile, ios::binary);
ofstream out(outputFile, ios::binary);
char c;
while (in.get(c)) {
out.put(c ^ key); // 简单异或加密
}
in.close();
out.close();
}
int main() {
string source = "secret.txt";
string encrypted = "secret_enc.dat";
string decrypted = "secret_dec.txt";
int key = 123; // 加密密钥
// 加密文件
encryptFile(source, encrypted, key);
cout << "文件加密完成!" << endl;
// 解密文件(加密的逆过程)
encryptFile(encrypted, decrypted, key);
cout << "文件解密完成!" << endl;
return 0;
}
总结与要点
结构体要点
知识点 | 关键内容 | 注意事项 |
---|---|---|
结构体定义 | struct 名称 { 成员列表 }; |
末尾分号不能少 |
结构体变量 | 结构体名 变量名; |
|
成员访问 | 变量名.成员名 |
使用点运算符 |
结构体数组 | 结构体名 数组名[大小]; |
|
结构体嵌套 | 结构体中可以包含其他结构体 |
文件操作要点
知识点 | 关键内容 | 注意事项 |
---|---|---|
文件流类 | ifstream (输入), ofstream (输出) |
需包含<fstream> |
打开文件 | 流对象.open(文件名, 模式) |
检查是否打开成功 |
关闭文件 | 流对象.close() |
|
文本读写 | << 和>> 运算符 |
|
二进制读写 | read() 和write() |
|
文件位置 | seekg() 和tellg() |
用于随机访问 |
结构体与文件结合要点
-
文本格式存储
- 优点:人类可读
- 缺点:占用空间大,解析复杂
-
二进制格式存储
- 优点:存储紧凑,读写快速
- 缺点:人类不可读,依赖结构体内存布局
-
注意事项
- 读写结构体数组时使用
sizeof
计算总大小 - 文件操作后必须检查是否成功
- 使用二进制模式打开二进制文件
- 不同平台可能有字节序差异
- 读写结构体数组时使用
学习建议
- 理解结构体的本质:自定义复合数据类型
- 掌握点运算符:访问结构体成员
- 练习结构体数组:处理批量数据
- 熟悉文件操作流程:打开→读写→关闭
- 区分文本和二进制模式:根据需求选择
- 结合应用:实现数据持久化存储
"结构体让数据组织更清晰,文件操作让数据持久化,二者结合是编程的重要技能!"
综合练习:通讯录管理系统
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
struct Contact {
string name;
string phone;
string email;
};
// 函数声明
void addContact(vector<Contact> &contacts);
void showContacts(const vector<Contact> &contacts);
void saveContacts(const vector<Contact> &contacts, string filename);
void loadContacts(vector<Contact> &contacts, string filename);
int main() {
vector<Contact> contacts;
loadContacts(contacts, "contacts.txt"); // 启动时加载数据
int choice;
do {
cout << "\n===== 通讯录管理系统 =====" << endl;
cout << "1. 添加联系人" << endl;
cout << "2. 显示所有联系人" << endl;
cout << "3. 保存到文件" << endl;
cout << "0. 退出" << endl;
cout << "请选择: ";
cin >> choice;
switch (choice) {
case 1: addContact(contacts); break;
case 2: showContacts(contacts); break;
case 3: saveContacts(contacts, "contacts.txt"); break;
}
} while (choice != 0);
return 0;
}
void addContact(vector<Contact> &contacts) {
Contact c;
cout << "输入姓名: ";
cin >> c.name;
cout << "输入电话: ";
cin >> c.phone;
cout << "输入邮箱: ";
cin >> c.email;
contacts.push_back(c);
cout << "联系人添加成功!" << endl;
}
void showContacts(const vector<Contact> &contacts) {
if (contacts.empty()) {
cout << "通讯录为空!" << endl;
return;
}
cout << "姓名\t电话\t邮箱" << endl;
for (const Contact &c : contacts) {
cout << c.name << "\t"
<< c.phone << "\t"
<< c.email << endl;
}
}
void saveContacts(const vector<Contact> &contacts, string filename) {
ofstream outFile(filename);
for (const Contact &c : contacts) {
outFile << c.name << ","
<< c.phone << ","
<< c.email << endl;
}
outFile.close();
cout << "数据保存成功!" << endl;
}
void loadContacts(vector<Contact> &contacts, string filename) {
ifstream inFile(filename);
if (!inFile) return;
contacts.clear();
string line;
while (getline(inFile, line)) {
// 解析CSV格式
Contact c;
size_t pos1 = line.find(',');
size_t pos2 = line.find(',', pos1+1);
c.name = line.substr(0, pos1);
c.phone = line.substr(pos1+1, pos2-pos1-1);
c.email = line.substr(pos2+1);
contacts.push_back(c);
}
inFile.close();
cout << "数据加载完成!" << endl;
}
- 参加人数
- 7
- 创建人