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

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

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

#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

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

C++语言基础 例程 二进制文件及其顺序读写

贺老师的教学链接  本课讲解 对比ASCII文件和二进制文件 //将short int x=12345写入文本文件 #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int main( ) { short int x=12345; ofstream outfile("binary.dat"); if(!outfile) { cerr<&l

C++语言基础 例程 案例:bmp文件格式剖析

贺老师的教学链接  本课讲解 附:二进制文件查看器及示例bmp文件 http://pan.baidu.com/s/1dDjf5uD 用程序读出BMP文件信息 //readbmp.h #ifndef READBMP_H_INCLUDED #define READBMP_H_INCLUDED typedef unsigned char BYTE; typedef unsigned short int UINT; typedef short int WORD; typedef int DWORD; t

C++语言基础 例程 案例:MyVector类的设计

贺老师的教学链接  本课讲解 //MyVector类的设计 #include <iostream> using namespace std; class MyVector //定义向量类 { public: MyVector(int m); //构造函数,共有m个元素的向量,元素值预置为0 MyVector(const MyVector &v); //复制构造函数 ~MyVector(); //析构函数:释放动态数组所占用的存储空间 friend istream &operat

C++语言基础 例程 案例:Time类的设计

贺老师的教学链接  本课讲解 #include <iostream> using namespace std; class CTime { private: unsigned short int hour; // 时 unsigned short int minute; // 分 unsigned short int second; // 秒 public: CTime(int h=0,int m=0,int s=0); void setTime(int h,int m,int s); //输

C++语言基础 例程 案例:一个接口,多种方法

贺老师的教学链接  本课讲解 用指针输出几何体 #include <iostream> using namespace std; class Point { public: Point(double x=0,double y=0); friend ostream & operator<<(ostream &,const Point &); protected: double x,y; }; Point::Point(double a,double b):x(

C++语言基础 例程 文件的随机读写

贺老师的教学链接  本课讲解 示例:写到尾再从头读 #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int main( ) { int a[10], b[10]; fstream iofile("f1.dat",ios::in|ios::out); if(!iofile) { cerr<<"open error!&quo

C++语言基础 例程 重载单目运算符

贺老师的教学链接  本课讲解 示例1:分数类对象的相反数 class CFraction { private: int nume; // 分子 int deno; // 分母 public: CFraction(int nu=0,int de=1):nume(nu),deno(de) {} CFraction operator-(const CFraction &c); //两个分数相减,结果要化简 CFraction operator-(); //取反一目运算 }; // 分数相减 CFrac

C++语言基础 例程 虚析构函数

贺老师的教学链接  本课讲解 问题的由来 #include <iostream> using namespace std; class Point { public: Point( ) { } ~Point() { cout<<"executing Point destructor"<<endl; } }; class Circle:public Point { public: Circle( ) { } ~Circle( ) { cout<&

C++语言基础 例程 应用系统开发:银行储蓄系统

贺老师的教学链接  本课讲解 说明:(1)下面的代码,只演示了利用链表作为存储结构的可选处理方法,本讲提到的其他方面的拓展,请感兴趣做下去的同学自行使用相关技术组合起来,形成一个完整的系统.(2)运行程序,登录用户名和密码,请阅读程序,从程序中找出.建议建立多文件项目,将代码拷贝到IDE中看.(3)本程序由我的2011级学生刘镇参加企业组织的实训中完成,原文在:点击打开链接 Record.h #ifndef HEADER_RECORD //条件编译 #define HEADER_RECORD #