C++打开含有数据的二进制文件报错,如何解决?

我用C++做了一个图书管理系统,代码如下。刚开始没有创建数据文件时运行正常,但往文件中添加数据之后再运行程序就报错,求大神帮忙分析一下原因,本人将感激不尽!

图片说明

调用堆栈:

图片说明

//book.h
#ifndef _book_h_
#define _book_h_
#include<iostream>
#include<string>
using namespace std;
class Book  //图书类
{
private:
    int note;  //删除标记(1:已删,0:未删)
    string number;  //图书编号
    string name;  //书名
    int onshelf;  //上架标志
    int count;  //上架数量
public:
    Book()
    {
        note = 0;
        onshelf = 0;
        count = 0;
    }
    string getname();  //获得书名
    int getnote();  //获得删除标记
    string getnumber();  //获得图书编号
    int getonshelf();  //获得上架标志(1.上架,0.下架)
    int getcount(); //获得上架数量
    void setname(string na);  //设置书名
    void delbook();  //删除图书
    void addbook(string n,string na);  //添加图书
    void addbook(int c);
    void borrowbook();  //借书操作
    void rebook();  //还书操作
    void list();  //输出图书列表
};
#endif

//reader.h
#ifndef _reader_h_
#define _reader_h_
#include<iostream>
#include<string>
using namespace std;
const int maxbor = 5;  //最大借阅量
class Reader
{
private:
    int note;  //删除标记(1:已删,0:未删)
    string number;  //读者编号
    string name;  //读者姓名
    string borbook[maxbor];  //所借图书
public:
    Reader() { note = 0; }
    string getname();  //获得姓名
    int getnote();  //获得删除标记
    string getnumber();  //获得读者编号
    void setname(string na);  //设置姓名
    void delreader();  //删除读者
    void addreader(string n, string na);  //添加读者
    void borrowbook(string bookid);  //借书操作
    void rebook(string bookid);  //还书操作
    void list();  //输出读者信息
};
#endif

//bdatabase.h
#ifndef _bdatadase_h_
#define _bdatabase_h_
#include<iostream>
#include"book.h"
using namespace std;
const int maxb = 100;  //最大图书种类数
class BDatabase
{
private:
    int top;  //图书记录指针
    Book book[maxb];  //图书记录
public:
    BDatabase();  //构造函数:读文件
    void clear();  //全部删除
    void addbook(string n, string na, int c);  //添加图书
    Book* search(string bookid);  //查找图书
    void list();  //输出图书信息
    void bookdata();  //图书库维护
    ~BDatabase();  //析构函数:写文件
};
#endif

//rdatabase.h
#ifndef _rdatadase_h_
#define _rdatabase_h_
#include<iostream>
#include"reader.h"
using namespace std;
const int maxr = 100;  //最大读者数
class RDatabase
{
private:
    int top;  //读者记录指针
    Reader read[maxr];  //读者记录
public:
    RDatabase();  //构造函数:读文件
    void clear();  //删除所有读者信息
    void addreader(string n, string na);  //添加读者
    Reader* search(string readerid);  //按编号查找
    void list();  //输出所有读者信息
    void readerdata();  //读者库维护
    ~RDatabase();  //析构函数:写文件
};
#endif

//book.cpp
#include<iomanip>
#include"book.h"
string Book::getname()
{
    return name;
}
int Book::getnote()
{
    return note;
}
string Book::getnumber()
{
    return number;
}
int Book::getonshelf()
{
    return onshelf;
}
int Book::getcount()
{
    return count;
}
void Book::setname(string na)
{
    name = na;
    cout << "图书更改成功" << endl;
}
void Book::addbook(string n, string na)
{
    note = 0;
    number = n;
    name = na;
    onshelf = 1; 
}
void Book::addbook(int c)
{
    count = count + c;
}
void Book::delbook()
{
    note = 1;
    cout << "图书删除成功" << endl;
}
void Book::borrowbook()
{
    if (count == 0)
        cout << "该图书已全部借出,不能借书!" << endl;
    else
    {
        count = count - 1;
        cout << "借书成功" << endl;
    }
}
void Book::rebook()
{
    count = count + 1;
    cout << "还书成功" << endl;
}
void Book::list()
{
    cout << setw(10) << number << setw(10) << name << setw(10) << onshelf << setw(10) << count << endl;
}

//reader.cpp
#include<iomanip>
#include"reader.h"
string Reader::getname()
{
    return name;
}
int Reader::getnote()
{
    return note;
}
string Reader::getnumber()
{
    return number;
}
void Reader::setname(string na)
{
    name = na;
    cout << "读者更改成功" << endl;
}
void Reader::addreader(string n, string na)
{
    note = 0;
    number = n;
    name = na;
    for (int i = 0; i < maxbor; i++)
        borbook[i] = "0";
}
void Reader::delreader()
{
    note = 1;
    cout << "读者删除成功" << endl;
}
void Reader::borrowbook(string bookid)
{
    for (int i = 0; i < maxbor; i++)
        if (borbook[i] == "0")
            borbook[i] = bookid;
}
void Reader::rebook(string bookid)
{
    for (int i = 0; i < maxbor; i++)
        if (borbook[i] == bookid)
            borbook[i] = "0";
}
void Reader::list()
{
    cout << setw(10) << number << setw(10) << name << setw(10);
    for (int i = 0; i < maxbor; i++)
        if (borbook[i] != "0")
            cout << borbook[i] << " ";
    cout << endl;
}

//bdatabase.cpp
#include<iostream>
#include<fstream>
#include<iomanip>
#include"bdatabase.h"
using namespace std;
BDatabase::BDatabase()
{
    Book s;
    top = -1;
    fstream file;
    file.open("book.dat", ios::in | ios::binary);
    while (1)
    {
        file.read((char*)& s, sizeof(s));
        if (!file)break;
        top++;
        book[top] = s;
    }
    file.close();
}
void BDatabase::clear()
{
    top = -1;
    cout << "全部图书删除成功" << endl;
}
Book* BDatabase::search(string bookid)
{
    for (int i = 0; i <= top; i++)
        if (book[i].getnumber() == bookid && book[i].getnote() == 0)
            return &book[i];
    return NULL;
}
void BDatabase::addbook(string n, string na,int c)
{
    Book* p = search(n);
    if (p == NULL)
    {
        top++;
        book[top].addbook(n, na);
        book[top].addbook(c);
    }
    else
        p->addbook(c);
    cout << "图书添加成功" << endl;
}
void BDatabase::list()
{
    cout << setw(10) << "图书编号" << setw(10) << "书名" << setw(10) << "上架标志" << setw(10) << "上架数量" << endl;
    for (int i = 0; i <= top; i++)
        if (book[i].getnote() == 0)
            book[i].list();
}
BDatabase::~BDatabase()
{
    fstream file;
    file.open("book.dat", ios::out | ios::binary | ios::app);
    for (int i = 0; i <= top; i++)
        if (book[i].getnote() == 0)
            file.write((char*)& book[i], sizeof(book[i]));
    file.close();
}
void BDatabase::bookdata()
{
    int choice = 1;
    string bookname;
    string bookid;
    int count;
    Book* b;
    while (choice != 0)
    {
        cout << "图书维护:" << endl;
        cout << "1:新增 2:更改 3:删除 4:查找 5:显示 6:全删 0:退出" << endl;
        cin >> choice;
        cin.ignore();
        switch (choice)
        {
        case 1:
            cout << "输入图书编号:";
            getline(cin, bookid);
            cout << "输入图书名:";
            getline(cin, bookname);
            cout << "输入添加数量:";
            cin >> count;
            cin.ignore();
            addbook(bookid, bookname, count);
            break;
        case 2:
            cout << "输入图书编号:";
            getline(cin, bookid);
            b = search(bookid);
            if (b == NULL)
            {
                cout << "该图书不存在!" << endl;
                break;
            }
            cout << "输入新的图书名:";
            getline(cin, bookname);
            b->setname(bookname);
            break;
        case 3:
            cout << "输入图书编号:";
            getline(cin, bookid);
            b = search(bookid);
            if (b == NULL)
            {
                cout << "该图书不存在!" << endl;
                break;
            }
            b->delbook();
            break;
        case 4:
            cout << "输入图书编号:";
            getline(cin, bookid);
            b = search(bookid);
            if (b == NULL)
            {
                cout << "该图书不存在!" << endl;
                break;
            }
            cout << setw(10) << "图书编号" << setw(10) << "书名" << setw(10) << "上架标志" << setw(10) << "上架数量" << endl;
            b->list();
            break;
        case 5:
            list(); break;
        case 6:
            clear(); break;
        }
    }
}

//rdatabase.cpp
#include<iostream>
#include<fstream>
#include<iomanip>
#include"rdatabase.h"
using namespace std;
RDatabase::RDatabase()
{
    Reader s;
    top = -1;
    ifstream file;
    file.open("reader.dat", ios::in | ios::binary);
    while (1)
    {
        file.read((char*)& s, sizeof(s));
        if (!file)break;
        top++;
        read[top] = s;
    }
    file.close();
}
void RDatabase::clear()
{
    top = -1;
    cout << "全部读者删除成功" << endl;
}
Reader* RDatabase::search(string readerid)
{
    for (int i = 0; i <= top; i++)
        if (read[i].getnumber() == readerid && read[i].getnote() == 0)
            return &read[i];
    return NULL;
}
void RDatabase::addreader(string n, string na)
{
    Reader* p = search(n);
    if (p == NULL)
    {
        top++;
        read[top].addreader(n, na);
        cout << "读者添加成功" << endl;
    }
    else
        cout << "该读者已存在!" << endl;
}
void RDatabase::list()
{
    cout << setw(10) << "读者编号" << setw(10) << "读者姓名" << setw(10) << "借书编号" << endl;
    for (int i = 0; i <= top; i++)
        if(read[i].getnote()==0)
            read[i].list();
}
RDatabase::~RDatabase()
{
    fstream file;
    file.open("reader.dat", ios::out | ios::binary | ios::app);
    for (int i = 0; i <= top; i++)
        if (read[i].getnote() == 0)
            file.write((char*)& read[i], sizeof(read[i]));
    file.close();
}
void RDatabase::readerdata()
{
    int choice = 1;
    string readername;
    string readerid;
    Reader* r;
    while (choice != 0)
    {
        cout << "读者维护:" << endl;
        cout << "1:新增 2:更改 3:删除 4:查找 5:显示 6:全删 0:退出" << endl;
        cin >> choice;
        cin.ignore();
        switch (choice)
        {
        case 1:
            cout << "输入读者编号:";
            getline(cin, readerid);
            cout << "输入读者姓名:";
            getline(cin, readername);
            addreader(readerid, readername);
            break;
        case 2:
            cout << "输入读者编号:";
            getline(cin, readerid);
            r = search(readerid);
            if (r == NULL)
            {
                cout << "该读者不存在!" << endl;
                break;
            }
            cout << "输入新的姓名:";
            getline(cin, readername);
            r->setname(readername);
            break;
        case 3:
            cout << "输入读者编号:";
            getline(cin, readerid);
            r = search(readerid);
            if (r == NULL)
            {
                cout << "该读者不存在!" << endl;
                break;
            }
            r->delreader();
            break;
        case 4:
            cout << "输入读者编号:";
            getline(cin, readerid);
            r = search(readerid);
            if (r == NULL)
            {
                cout << "该读者不存在!" << endl;
                break;
            }
            cout << setw(10) << "读者编号" << setw(10) << "读者姓名" << setw(10) << "借书编号" << endl;
            r->list();
            break;
        case 5:
            list(); break;
        case 6:
            clear(); break;
        }
    }
}

//library.cpp
#include"reader.h"
#include"rdatabase.h"
#include"book.h"
#include"bdatabase.h"
#include<iostream>
using namespace std;
int main()
{
    int choice = 1;
    string bookid, readerid;
    RDatabase ReaderDB;
    BDatabase BookDB;
    Reader* r;
    Book* b;
    cout << "欢迎进入“小小图书馆”管理软件" << endl << endl;
    while (choice != 0)
    {
        cout << "1: 借书 2: 还书 3: 图书维护 4: 读者维护 0: 离开" << endl;
        cin >> choice;
        cin.ignore();
        switch (choice)
        {
        case 1:
            system("cls");
            cout << "输入借书读者编号";
            getline(cin, readerid);
            cout << "输入图书编号";
            getline(cin, bookid);
            r = ReaderDB.search(readerid);
            if (r == NULL)
            {
                cout << "该读者不存在,不能借书!" << endl;
                break;
            }
            b = BookDB.search(bookid);
            if (b == NULL)
            {
                cout << "该图书不存在,不能借书!" << endl;
                break;
            }
            b->borrowbook();
            r->borrowbook(b->getnumber());
            break;
        case 2:
            system("cls");
            cout << "输入还书读者编号";
            getline(cin, readerid);
            cout << "输入图书编号";
            getline(cin, bookid);
            r = ReaderDB.search(readerid);
            if (r == NULL)
            {
                cout << "该读者不存在,不能还书!" << endl;
                break;
            }
            b = BookDB.search(bookid);
            if (b == NULL)
            {
                cout << "该图书不存在,不能还书!" << endl;
                break;
            }
            b->rebook();
            r->rebook(b->getnumber());
            break;
        case 3:
            system("cls");
            BookDB.bookdata(); break;
        case 4:
            system("cls");
            ReaderDB.readerdata(); break;
        }
    }
    return 0;
}
c++

1个回答

ok,看了你的调用堆栈哈,很确定地说,是因为你直接把string对象的二进制内容写入到文件了,string对象维护的是存储字符串内容的指针,就是说你把存储字符串的地址写入了文件,而不是把字符串里面存储的内容写入文件。

weixin_44905661
ZHANG H. 受教了,谢谢!
12 个月之前 回复
weixin_44905661
ZHANG H. 截图已发,谢谢!
12 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问