大佬 谁能帮我看看 这里代码哪里出错了 一直借不出书来,下面是代码 可以帮我看看

#include "StuList.h"
#include"BSTree.h"
#include <string>
#include <sstream> // 添加这个头文件以使用 std::istringstream
#include <limits> // 包含limits头文件以使用std::numeric_limits
void op_user_menu(); //用户操作菜单函数
void Register(SqList &L); //用户注册函数,输入用户信息X,插入到表L
void Log_in(SqList L); //用户登录函数,输入学号和密码进行登录验证
void Log_out(SqList &L);//用户注销函数,输入学号,在顺序表中删除该用户
void Modify_Password(SqList &L);//用户密码修改函数,输入学号,修改该用户的登录密码
void File_in_List(SqList &L); //导入数据函数:打开student.txt文件,导入用户信息到顺序表L
void List_out_file(SqList L);//导出数据函数:将顺序表L中的数据导出到student.txt保存
void PrintList(SqList L);//用户信息显示函数:按行显示顺序表L中的用户信息。

void Borrow_Book(SqList &students, BSTree &books, string studentNum);


int main() {

    op_user_menu();


}


void op_user_menu() //用户操作菜单函数
{
    int op;
    SqList L; // 定义单链表变量L

    File_in_List(L); // 导入用户数据到表L

    do {
        cout << endl;
        cout << "/***********************输入数字进行操作选择************************/" << endl;
        cout << "1.注册" << endl;
        cout << "2.登录" << endl;
        cout << "3.输入学号修改登录密码" << endl;
        cout << "4.输入学号进行账号注销" << endl;
        cout << "5.显示所有学生信息" << endl;
        cout << "0.保存并退出程序" << endl;
        cout << "请输入: ";

        // 检查输入是否为数字
        if (!(cin >> op)) {
            // 如果输入不是数字,清除输入流的错误标志
            cin.clear();
            // 忽略错误输入后的所有字符
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "输入无效,请重新输入: ";
            continue; // 继续循环,等待用户重新输入
        }

        // 检查输入是否在1到5之间
        if (op < 1&&op!=0 || op > 5 ) {
            cout << "输入无效,请输入1到5之间的数字: ";
            continue; // 继续循环,等待用户重新输入
        }

        // 根据用户输入执行相应操作
        switch (op) {
            case 1:
                Register(L);
                break;
            case 2:
                Log_in(L);
                break;
            case 3:
                Modify_Password(L);
                break;
            case 4:
                Log_out(L);
                break;
            case 5:
                PrintList(L);
                break;
            case 0:
                cout << "数据已保存,程序退出。" << endl;
                return; // 退出函数,结束程序
            default:
                // 如果输入的数字不在1到5之间,但已经通过了之前的检查,这里不应该执行
                break;
        }
    } while (true); // 无限循环,直到用户选择退出
}

 // 用户注册函数
void Register(SqList &L) {
    
     student newStudent;
     cout << "输入学号:" << endl;
     cin >> newStudent.num;
     cout << "输入姓名:" << endl;
     cin >> newStudent.name;
     cout << "输入专业:" << endl;
     cin >> newStudent.major;
     cout << "输入密码:" << endl;
     cin >> newStudent.password;

     // 插入到顺序表
     int i = L.length + 1; // 新元素插入的位置
     if (ListInsert_Sq(L, i, newStudent) == OK) {
         cout << "注册成功!" << endl;

         // 将新插入的学生信息写入到student.txt文件中
         fstream file("student.txt", ios::app); // 打开文件用于追加内容
         if (file.is_open()) {
             try {
                 file << newStudent.num << "\t" << newStudent.name << "\t" << newStudent.major << "\t" << newStudent.password << endl;
                 file.close(); // 关闭文件
                 cout << "学生信息录入成功!" << endl; // 添加成功提示信息
             } catch (const exception& e) {
                 cerr << "写入文件时发生错误: " << e.what() << endl;
             }
         } else {
             cerr << "无法打开文件以写入数据!" << endl;
         }
     } else {
         cout << "注册失败,可能是因为顺序表已满。" << endl;
     }
}


    
// 用户登录函数
void Log_in(SqList L)
{
     
      BSTree T;
    int j;
    string login_user, login_pass;
    cout << "请输入学号和密码进行登录" << endl;
    cout << "学号:" << endl;
    cin >> login_user;
    cout << "密码:" << endl;
    cin >> login_pass;

    // 根据学号进行查找
    j = LocateElem_Sq(L, login_user);
    if (j && L.elem[j].password == login_pass)
    {
        cout << "登录成功" << endl;
        // 登录成功后,将学号存储在变量中
        string studentNum = login_user;
        
        // 进入借书菜单
        int op;
        do {
            cout << endl;
            cout << "/***********************输入数字进行操作选择************************/" << endl;
            cout << "1.借书" << endl;
            cout << "2.还书" << endl;
            cout << "0.保存并退出程序" << endl;
            cout << "请输入: ";

            // 检查输入是否为数字
            if (!(cin >> op)) {
                // 如果输入不是数字,清除输入流的错误标志
                cin.clear();
                // 忽略错误输入后的所有字符
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "输入无效,请重新输入: ";
                continue; // 继续循环,等待用户重新输入
            }

            // 检查输入是否在1到3之间
            if (op < 1 && op != 0 || op > 2) {
                cout << "输入无效,请输入1到2之间的数字: ";
                continue; // 继续循环,等待用户重新输入
            }

            // 根据用户输入执行相应操作
            switch (op) {
                case 1:
                // 创建一个BSTree类型的变量
             
                // 初始化BSTree
                BSTree books;
                // 使用已存储的学号调用借书函数
                Borrow_Book(L, books, studentNum);
                break;
                case 2:
                    // 还书函数
                   // Return_Book(L, T);
                    break;
                case 0:
                    cout << "数据已保存,程序退出。" << endl;
                    return; // 退出函数,结束程序
                default:
                    // 如果输入的数字不在1到5之间,但已经通过了之前的检查,这里不应该执行
                    break;
            }
        } while (true); // 无限循环,直到用户选择退出
    } else {
        cout << "账号密码错误,重新输入" << endl;
    }
}


        
        

        
        
        

    
    
    

               
    


// 借书功能实现
// 借书功能实现
void Borrow_Book(SqList &students, BSTree &books, string studentNum) {
    string bookId;
    int studentIndex; // 声明studentIndex变量
    BSTNode *bookNode; // 声明bookNode变量

    cout << "请输入要借阅的图书ISBN号: ";
    cin >> bookId;

    // 查找图书
    bookNode = SearchBST(books, bookId); // 声明并初始化bookNode变量
    if (bookNode == NULL) {
        cout << "图书不存在。" << endl;
        return;
    }

    // 检查库存
    if (bookNode->data.num <= 0) {
        cout << "图书已借完。" << endl;
        return;
    }

    // 更新库存并记录借阅
    bookNode->data.num--;
    studentIndex = LocateElem_Sq(students, studentNum); // 假设LocateElem_Sq函数返回学生在顺序表中的索引
    if (studentIndex != -1) {
        students.elem[studentIndex].borrowedBooks.push_back(bookNode->data);
        cout << "借书成功!" << endl;

        // 将借书信息写入到stu_borrow.txt文件中
        ofstream outFile("stu_borrow.txt", ios::app); // 打开文件用于追加内容
        if (outFile.is_open()) {
            outFile << studentNum << "\t" << bookId << endl;
            outFile.close();
        } else {
            cerr << "无法打开文件以写入数据!" << endl;
        }
    } else {
        cout << "未找到该学生信息。" << endl;
    }
}

 // 用户注销函数
void Log_out(SqList &L)
{
    int j;
    string login_user1,login_user2;
    cout<<"输入学号进行注销"<<endl;
    cout<<"学号:"<<endl;
    cin>>login_user1;
    cout<<"再次输入学号确认"<<endl;
    cin>>login_user2;
    while (login_user1!=login_user2 )
    {
        cout<<"账号输入错误,重新输入"<<endl;

        cout<<"输入学号进行注销"<<endl;
        cout<<"学号:"<<endl;
        cin>>login_user1;
        cout<<"再次输入学号确认"<<endl;
        cin>>login_user2;
    }
    j=LocateElem_Sq(L,login_user1);
    if (j!=0)
    {
        ListDelete_Sq(L,j);
        cout<<"注销账号成功"<<endl;
    }
    else cout<<"输入账号不存在"<<endl;
    return ;

}

 // 用户信息修改函数
void Modify_Password(SqList &L)
{
    int j;
    string login_user,pass1,pass2;
    cout<<"输入学号进行信息修改"<<endl;
    cout<<"学号:"<<endl;
    cin>>login_user;
    j=LocateElem_Sq(L,login_user);
    if (j!=0)
    {
        cout<<"新密码:"<<endl;
        cin>>pass1;
        cout<<"再次输入新密码:"<<endl;
        cin>>pass2;
        while (pass1!=pass2)
        {
            cout<<"两次密码不一致,重新输入"<<endl<<endl;
            cout<<"新密码:"<<endl;
            cin>>pass1;
            cout<<"再次输入新密码:"<<endl;
            cin>>pass2;
        }
        L.elem[j].password=pass1;
        cout<<"密码修改成功"<<endl;
    }
    else
        cout<<"该用户不存在"<<endl;
    return ;
}


void File_in_List(SqList &L) //将文件中的数据写入到L
{
    ElemType1 e;
    fstream file;
    InitList_Sq(L);
    int i = 1;
    file.open("student.txt");
    if (!file) {
        cout << "错误!未找到文件!" << endl;
        exit(ERROR);
    }
    while (file >> e.num >> e.name >> e.major >> e.password) {
        ListInsert_Sq(L, i, e);
        i++;
    }
    cout << "输入 student.txt 信息完毕\n\n";
    file.close();
}

void List_out_file(SqList L) //表L的数据写回文件book.txt
{
    int i;
    student e;
    
    fstream file("student.txt", fstream::out | ios_base::trunc); //打开时清空文件
    if (!file) {
        cout << "错误!未找到文件!" << endl;
        exit(ERROR);
    }
    
    for (i=1;i<L.length;i++)
    {
        e=L.elem[i];
        file << left << e.num<< "\t" << left << e.name << "\t" << left << e.major << "\t" << left << e.password <<endl;
    }
    e=L.elem[L.length];
    file << left << e.num<< "\t" << left << e.name << "\t" << left << e.major << "\t" << left << e.password;
    
    file.close();
}


//按行输出用户的学号、姓名、专业
void PrintList(SqList L) 
{
    int i;
    for(i=1;i<=L.length;i++)
        cout<<L.elem[i].num<<" "<<L.elem[i].name<<" "<<L.elem[i].major<<endl;
    cout<<endl;
}

//
//StuList.h文件包含了顺序表结构的类型描述、基本操作的实现
//

#include"BSTree.h"
#include<iostream>
#include<string>
#include<fstream>
#include <vector>
using namespace std;


#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100            //顺序表可能达到的最大长度

/*程序中相关数据类型定义*/
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。

typedef struct  {
    string    num;//学号
    string    name;//姓名
    string major;//专业
    string password;//登录密码
    vector<Book> borrowedBooks; // 存储学生借阅的书籍信息
} student;  //定义用户信息类型student

typedef student ElemType1; //顺序表中的数据元素类型定义为student

typedef struct {
    ElemType1 * elem; //存储空间的基地址,从下标1开始写数据
    int length; //当前长度
} SqList;  //定义顺序表类型

Status InitList_Sq(SqList &L) { //算法2.1 顺序表的初始化
    //构造一个空的顺序表L
    L.elem = new ElemType1[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
    if (!L.elem)
        exit(OVERFLOW); //存储分配失败退出
    L.length = 0; //空表长度为0
    return OK;
}

Status GetElem(SqList L, int i, ElemType1 &e) {//算法2.2 顺序表的取值
    if (i < 1 || i > L.length)
        return ERROR; //判断i值是否合理,若不合理,返回ERROR
    e = L.elem[i]; //elem[i]单元存储第i个数据元素
    return OK;
}

int LocateElem_Sq(SqList L, string stu_num) { //根据学号进行查找,查找成功返回位序
    for (int i = 1; i <=L.length; i++)
        if (L.elem[i].num == stu_num)
            return i ;//查找成功,返回位序
    return -1;//查找失败,返回0
}

Status ListInsert_Sq(SqList &L, int i, ElemType1 e) { //算法2.4 顺序表的插入
    //在顺序表L中第i个位置之前插入新的元素e
    //i值的合法范围是1<=i<=L.length+1
    if ((i < 1) || (i > L.length + 1))
        return ERROR; //i值不合法
    if (L.length == MAXSIZE)
        return ERROR; //当前存储空间已满
    for (int j = L.length; j >= i; j--)
        L.elem[j + 1] = L.elem[j]; //插入位置及之后的元素后移
    L.elem[i] = e; //将新元素e放入第i个位置
    ++L.length; //表长增1
    return OK;
}

Status ListDelete_Sq(SqList &L, int i) { //算法2.5 顺序表的删除
    //在顺序表L中删除第i个元素,并用e返回其值
    //i值的合法范围是1<=i<=L.length
    if ((i < 1) || (i > L.length))
        return ERROR; //i值不合法
    for (int j = i; j < L.length; j++)
        L.elem[j] = L.elem[j+1]; //被删除元素之后的元素前移
    --L.length; //表长减1
    return OK;
}

//算法7.4 二叉排序树的递归查找
//算法7.5 二叉排序树的插入
//算法7.6 二叉排序树的创建
//算法 7.7 二叉排序树的删除

#ifndef BSTREE_H
#define BSTREE_H
#include<iostream>
#include<fstream>
#include <string>
#include <iomanip>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define  MAXSIZE 100

typedef struct  {
    string id;     //ISBN
    string name;   //书名
    double price;  //定价
    int num;    //库存
} Book;   //定义图书信息数据类型

typedef string Keytype; //定义查找关键字类型Keytype为string类型
typedef Book ElemType2;

typedef struct BSTNode{
    ElemType2 data;    //结点数据域,存数据元素
    BSTNode *lchild,*rchild;    //左右孩子指针
} BSTNode,* BSTree;  //二叉排序树结点及二叉排序树类型定义

// 定义BSTree类型


//算法7.4 二叉排序树的递归查找
BSTree SearchBST(BSTree T,Keytype key) {  //根据ISBN号查找
  //在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
  //若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
  if((!T)|| key==T->data.id) return T;                           //查找结束
  else if (key<T->data.id)  return SearchBST(T->lchild,key);    //在左子树中继续查找
  else return SearchBST(T->rchild,key);                           //在右子树中继续查找
} // SearchBST

//算法7.5 二叉排序树的插入
void InsertBST(BSTree &T,ElemType2 e ) {
  //当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
  if(!T) {                                //找到插入位置,递归结束
         BSTree S = new BSTNode;                    //生成新结点*S
         S->data = e;                          //新结点*S的数据域置为e   
         S->lchild = S->rchild = NULL;    //新结点*S作为叶子结点
         T =S;                            //把新结点*S链接到已找到的插入位置
  }
  else if (e.id< T->data.id) 
      InsertBST(T->lchild, e );            //将*S插入左子树
  else if (e.id> T->data.id) 
      InsertBST(T->rchild, e);            //将*S插入右子树
}// InsertBST


BSTNode* FindMin( BSTree T )
{
    BSTNode*  p;
    if(T==NULL) return NULL; //空树返回空指针
    p=T;
    while(p->lchild) //找最左边的
    {
        p=p->lchild;
    }
    return p;
}

//算法 7.7 二叉排序树的删除


void DeleteBST(BSTree &T, Keytype key) {
    BSTNode *temp;
    if (!T) return; // 空树,删除失败

    if (T->data.id > key) {
        DeleteBST(T->lchild, key); // 在左子树中递归删除
    } else if (T->data.id < key) {
        DeleteBST(T->rchild, key); // 在右子树中递归删除
    } else {
        // 找到要删除的节点
        if (!T->lchild && !T->rchild) {
            // 没有子节点,直接删除
            delete T;
            T = NULL;
        } else if (!T->lchild) {
            // 只有右子节点,用右子节点替换当前节点
            BSTNode *temp = T;
            T = T->rchild;
            delete temp;
        } else if (!T->rchild) {
            // 只有左子节点,用左子节点替换当前节点
            BSTNode *temp = T;
            T = T->lchild;
            delete temp;
        } else {
            // 有两个子节点,找到右子树的最小节点
            temp = FindMin(T->rchild);
            // 用右子树的最小节点替换当前节点
            T->data = temp->data;
            // 删除右子树的最小节点
            DeleteBST(T->rchild, temp->data.id);
        }
    }
}

#endif // BSTREE_H

  

  • 28
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值