C++语言基础 例程 二进制文件应用案例

简介: 贺老师的教学链接  本课讲解系统升级第一步:转换现有数据格式(附:数据文件点击打开链接)#include <iostream>#include <fstream>#include <cstdlib>using namespace std;typedef struct{ int NO; char name[8]; in

贺老师的教学链接  本课讲解


系统升级第一步:转换现有数据格式(附:数据文件点击打开链接

#include <iostream> #include <fstream> #include <cstdlib> using namespace std; typedef struct { int NO; char name[8]; int chinese; int math; int english; int Comprehensive; int total; } Student; //高考学生信息 const int maxNum = 10000; void display(Student*, int); int main() { ifstream asciiFile("asciidata.txt", ios::in); if(!asciiFile) { cerr<<"cannot open ascii file!"<<endl; exit(1); } int stuNum = 0; Student students[maxNum]; //读入文本文件 while(!asciiFile.eof()) { asciiFile>>students[stuNum].NO; asciiFile>>students[stuNum].name; asciiFile>>students[stuNum].chinese; asciiFile>>students[stuNum].math; asciiFile>>students[stuNum].english; asciiFile>>students[stuNum].Comprehensive; asciiFile>>students[stuNum].total; stuNum++; } asciiFile.close(); display(students, stuNum); //写入到二进制文件 int i; ofstream binaryFile("binarydata.dat", ios::out|ios::binary); if(!binaryFile) { cerr<<"cannot open binary file!"<<endl; exit(1); } binaryFile.write((char*)&stuNum, sizeof(stuNum)); for(i=0; i<stuNum; ++i) { binaryFile.write((char*)&students[i], sizeof(Student)); } binaryFile.close(); return 0; } void display(Student *s, int n) { cout<<"共"<<n<<"名考生:"<<endl; int i; for(i=0; i<n; ++i) { cout<<i<<": "<<s[i].NO<<"\t"; cout<<s[i].name<<"\t"; cout<<s[i].chinese<<"\t"; cout<<s[i].math<<"\t"; cout<<s[i].english<<"\t"; cout<<s[i].Comprehensive<<"\t"; cout<<s[i].total<<"\t"<<endl; } }


用二进制文件完成业务
#include <iostream> #include <fstream> #include <cstdlib> using namespace std; typedef struct { int NO; char name[8]; int chinese; int math; int english; int Comprehensive; int total; } Student; //高考学生信息 void display(Student*, int); void sort(Student*, int); int main() { int stuNum = 0; Student *students; fstream binaryFile("binarydata.dat", ios::in|ios::out|ios::binary); if(!binaryFile) { cerr<<"cannot open binary file!"<<endl; exit(1); } //读入考生人数 binaryFile.read((char*)&stuNum, sizeof(stuNum)); //读入数据 students = new Student[stuNum]; int i; for(i=0; i<stuNum; ++i) { binaryFile.read((char*)&students[i], sizeof(Student)); } display(students, stuNum); //各种操作(例排序,还可以查找、修改等) sort(students, stuNum); //查看操作结果 //display(students, stuNum); //将数据再写入文件 binaryFile.seekg(0, ios::beg); binaryFile.write((char*)&stuNum, sizeof(stuNum)); for(i=0; i<stuNum; ++i) { binaryFile.write((char*)&students[i], sizeof(Student)); } //关闭文件 binaryFile.close(); return 0; } void display(Student *s, int n) { cout<<"共"<<n<<"名考生:"<<endl; int i; for(i=0; i<n; ++i) { cout<<i<<": "<<s[i].NO<<"\t"; cout<<s[i].name<<"\t"; cout<<s[i].chinese<<"\t"; cout<<s[i].math<<"\t"; cout<<s[i].english<<"\t"; cout<<s[i].Comprehensive<<"\t"; cout<<s[i].total<<"\t"<<endl; } } void sort(Student *s, int n) { int i, j; Student temp; //用于交换的中间变量 for (i=0; i<n-1; i++) for(j=0; j<n-i-1; j++) if (s[j].NO>s[j+1].NO) { temp=s[j]; s[j]=s[j+1]; s[j+1]=temp; } return; }


索引文件的建立
#include <iostream> #include <fstream> #include <cstdlib> using namespace std; typedef struct { int NO; char name[8]; int chinese; int math; int english; int Comprehensive; int total; } Student; //高考学生信息 typedef struct { int NO; long offset; //数据在文件中的偏移量 } StudentIndex; //高考学生索引 void createIndex(); void writeIndex(StudentIndex *si, int n); int main() { createIndex(); return 0; } /* 功能:创建索引 */ void createIndex() { int stuNum; StudentIndex *studentsIndex; //索引表的起始地址 Student student; ifstream binaryFile("binarydata.dat", ios::in|ios::binary); if(!binaryFile) { cerr<<"cannot open binary file!"<<endl; exit(1); } //建立索引 binaryFile.read((char*)&stuNum, sizeof(stuNum)); //读入实际人数 //读入数据,建立未排序的索引表 studentsIndex = new StudentIndex[stuNum]; int i, j; long mOffset; for(i=0; i<stuNum; ++i) { mOffset = binaryFile.tellg(); binaryFile.read((char*)&student, sizeof(Student)); studentsIndex[i].NO = student.NO; studentsIndex[i].offset = mOffset; //记录对应学号学生数据的偏移量 } //关闭数据文件 binaryFile.close(); //为索引表排序 StudentIndex temp; //用于交换的中间变量 for (i=0; i<stuNum-1; i++) for(j=0; j<stuNum-i-1; j++) if (studentsIndex[j].NO>studentsIndex[j+1].NO) { temp=studentsIndex[j]; studentsIndex[j]=studentsIndex[j+1]; studentsIndex[j+1]=temp; } //将建好的索引表通过文件存储 writeIndex(studentsIndex, stuNum); return; } /* 功能:将索引写入文件 参数:si - 索引表起始地址;n - 考生人数,索引记录条数 */ void writeIndex(StudentIndex *si, int n) { //打开文件 ofstream indexFile("binarydata.idx", ios::out|ios::binary); if(!indexFile) { cerr<<"cannot open index file!"<<endl; exit(1); } int i; for(i=0; i<n; ++i) { //indexFile<<si[i].NO<<"\t"<<si[i].offset<<endl; //索引用作文本文件时 indexFile.write((char*)&si[i], sizeof(StudentIndex)); //索引用二进制文件时 } //关闭文件 indexFile.close(); return; }


索引文件的利用
#include <iostream> #include <fstream> #include <cstdlib> using namespace std; typedef struct { int NO; char name[8]; int chinese; int math; int english; int Comprehensive; int total; } Student; //高考学生信息 typedef struct { int NO; long offset; //数据在文件中的偏移量 } StudentIndex; //高考学生索引 //为方便起见,下面变量用全局变量表示。若用局部变量,各模块间通过引用传递参数亦可 fstream dataFile, indexFile; int stuNum, maxNum; StudentIndex *studentsIndex; //索引表入口地址 //函数声明 void createIndex(); void writeIndex(StudentIndex *si, int n); void init(); void work(); int chooseInMenu(); void done(); void displayByIndex(); void displayStudent(Student &s); int main() { char yn; cout<<"需要重建索引吗?(Y/N)"; cin>>yn; if('Y'==yn||'y'==yn) createIndex(); init(); work(); done(); return 0; } /* 功能:创建索引 */ void createIndex() { int stuNum; StudentIndex *studentsIndex; //索引表的起始地址 Student student; ifstream binaryFile("binarydata.dat", ios::in|ios::binary); if(!binaryFile) { cerr<<"cannot open binary file!"<<endl; exit(1); } //建立索引 binaryFile.read((char*)&stuNum, sizeof(stuNum)); //读入实际人数 //读入数据,建立未排序的索引表 studentsIndex = new StudentIndex[stuNum]; int i, j; long mOffset; for(i=0; i<stuNum; ++i) { mOffset = binaryFile.tellg(); binaryFile.read((char*)&student, sizeof(Student)); studentsIndex[i].NO = student.NO; studentsIndex[i].offset = mOffset; //记录对应学号学生数据的偏移量 } //关闭数据文件 binaryFile.close(); //为索引表排序 StudentIndex temp; //用于交换的中间变量 for (i=0; i<stuNum-1; i++) for(j=0; j<stuNum-i-1; j++) if (studentsIndex[j].NO>studentsIndex[j+1].NO) { temp=studentsIndex[j]; studentsIndex[j]=studentsIndex[j+1]; studentsIndex[j+1]=temp; } //将建好的索引表通过文件存储 writeIndex(studentsIndex, stuNum); return; } /* 功能:将索引写入文件 参数:si - 索引表起始地址;n - 考生人数,索引记录条数 */ void writeIndex(StudentIndex *si, int n) { //打开文件 ofstream indexFile("binarydata.idx", ios::out|ios::binary); if(!indexFile) { cerr<<"cannot open index file!"<<endl; exit(1); } int i; for(i=0; i<n; ++i) { //indexFile<<si[i].NO<<"\t"<<si[i].offset<<endl; //索引用作文本文件时 indexFile.write((char*)&si[i], sizeof(StudentIndex)); //索引用二进制文件时 } //关闭文件 indexFile.close(); return; } /* 功能:初始化,为几个全局变量获得初值 */ void init() { //第一件工作:打开数据文件 dataFile.open("binarydata.dat", ios::in|ios::out|ios::binary); if(!dataFile) { cerr<<"cannot open data file!"<<endl; exit(1); } //读入考生人数 dataFile.read((char*)&stuNum, sizeof(stuNum)); //读入实际人数 maxNum = stuNum * 1.1; //最多人数多留10%的空间,以备增加数据用(本例用不着) studentsIndex = new StudentIndex[maxNum]; //为索引表分配空间 //从索引文件中读取数据,保存在索引表中 //在业务运行过程中,索引表独立工作,以发挥其速度优势 //打开文件 indexFile.open("binarydata.idx", ios::in|ios::binary); if(!indexFile) { cerr<<"cannot open index file!"<<endl; exit(1); } int i; for(i=0; i<stuNum; ++i) { indexFile.read((char*)&studentsIndex[i], sizeof(StudentIndex)); //索引用二进制文件时 } //关闭文件 indexFile.close(); return; } /* 功能:完成"善后"工作 */ void work() { int iChoice; //用于选择系统功能 //办理业务 do { iChoice = chooseInMenu(); //从菜单中获得功能代码 switch(iChoice) { case 1: displayByIndex(); //按索引显示 break; case 2: out<<"请设计函数searchStudent(),输入考号,在索引表中二分查找,然后到数据文件中读取数据并显示"<<endl; break; case 3: cut<<"请设计函数updateStudent(),输入考号,在索引表中二分查找,输入新值,并且更新数据文件中的数据"<<endl; break; case 4: cout<<"请设计函数addStudent(),输入考生息,保存到数据文件的最后,将新考生的信息插入在索引表中的合适位置,以使索引表与数据文件仍然同步"<<endl; break; case 5: cout<<"索引表与数据文件相配合开展工作,在工程中太实用了,请自提需求,尝试实现"<<endl; break; case 0: cout<<"欢迎您再来. "<<endl; } } while(iChoice); cout<<"什么也没有做!"<<endl; } /* 功能:显示菜单并由业务员选择 返回值:用户选择的功能,范围0-9 */ int chooseInMenu() { int i; while(1) { cout<<endl; cout<<"+---------------+"<<endl; cout<<"+ 1 按索引显示 +"<<endl; cout<<"+ 2 查询考生 +"<<endl; cout<<"+ 3 更新数据 +"<<endl; cout<<"+ 4 增加考生 +"<<endl; cout<<"+ 5 增加考生 +"<<endl; cout<<"+ 0 退出 +"<<endl; cout<<"+---------------+"<<endl; cout<<"请输入操作指令:"<<endl; cin>>i; if(i>=0 && i<=5) break; else cout<<"请重新选择功能\n"<<endl; } return i; } void done() { //关闭数据文件 dataFile.close(); //若数据进行过增删改,索引表会发生变化,重新保存到文件中 writeIndex(studentsIndex, stuNum); } void displayByIndex() { Student stu; indexFile.seekg(ios::beg); int i; long location; cout<<"共"<<stuNum<<"名考生:"<<endl; for(i=0; i<stuNum; ++i) { location = studentsIndex[i].offset; dataFile.seekg(location, ios::beg); dataFile.read((char*)&stu, sizeof(Student)); cout<<i<<": "; displayStudent(stu); } } void displayStudent(Student &s) { cout<<s.NO<<"\t"; cout<<s.name<<"\t"; cout<<s.chinese<<"\t"; cout<<s.math<<"\t"; cout<<s.english<<"\t"; cout<<s.Comprehensive<<"\t"; cout<<s.total<<"\t"<<endl; }


目录
相关文章
|
1月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
92 11
|
3月前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
360 12
|
8月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
232 15
|
8月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
182 8
|
9月前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
310 12
|
10月前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
274 5
|
10月前
|
存储 C++
【C++面向对象——输入输出流】处理二进制文件(头歌实践教学平台习题)【合集】
本任务要求使用C++读取二进制文件并在每行前添加行号后输出到控制台。主要内容包括: 1. **任务描述**:用二进制方式打开指定文件,为每一行添加行号并输出。 2. **相关知识**: - 流类库中常用的类及其成员函数(如`iostream`、`fstream`等)。 - 标准输入输出及格式控制(如`cin`、`cout`和`iomanip`中的格式化函数)。 - 文件的应用方法(文本文件和二进制文件的读写操作)。 3. **编程要求**:编写程序,通过命令行参数传递文件名,使用`getline`读取数据并用`cout`输出带行号的内容。 4. **实验步骤**:参考实验指
253 5
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
263 5
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
297 5
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)
137 0
下一篇