系统升级第一步:转换现有数据格式(附:数据文件点击打开链接)
#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; }
时间: 2024-10-21 22:28:57