为啥下面的代码在scanf进行输入的时候会程序崩溃,and有给我下面代码的一些建议吗,自我感觉写的不是很好,有很多地方都复杂化了,但不知道如何优化
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define MAX 100
#include<stdio.h>
#include<stdlib.h>
#include<String.h>
#include<time.h>
//struct comment;
//struct book;
typedef struct student1//定义学生账号结构体
{
int account;//账号
char password[MAX];//密码
char name[MAX];//姓名
char student_number[MAX];//学号
//int num;//借书数量
//Book book[10];//借的书,并且最多只能借10本
};
typedef struct
{
struct student1 student;
char data[MAX];
time_t timep;
char time[MAX];
}Comment;
typedef struct book//定义书结构体
{
char name[MAX];//书名
char number[MAX];//书的编号
double price;//书的价格
int num;//书的数量
Comment comment[MAX];
int num_comment;//评论的数量
struct student1 student[MAX];
int num_student;
}Book;
typedef struct
{
Book book[MAX];
int num_book;
struct student1 student;
int num_student;
Comment comment[MAX];
int num_commnet;
}Student;
typedef struct Node//定义书链表
{
Book data;
struct Node* next;
}LinkList_book;
typedef struct Node1//定义学生账户链表
{
Student data;
struct Node1* next;
}LinkList_student;
//全局变量
//LinkList_book* L_book;//书链表
//LinkList_student* L_student;//学生账户链表
void CreateList_book();
void CreateList_student();
void welcome();
void Librarian();
void User();
void insert_book(Book book);
void insert_student(Student student);
LinkList_student* Find_student(int account);
LinkList_book* Find_book(char name[]);
Book Find_comment(char comment[]);//查找评论所在的书籍
void DispBook(LinkList_book* book);//单本
void Disp_Book();//所有
int Delete_book(char name[]);
int Delete_student(char name[]);
void Sort_book();
void saveInfoToFile_book(const char* FileName);
void saveInfoToFile_student(const char* FileName);
void readInfoToFile_book(const char* FileName);
void readInfoToFile_student(const char* FileName);
void DispComment_book(Book book);
void DispComment_student(Student student);
Library.cpp:
#include"Library.h"
extern LinkList_book* L_book;
extern LinkList_student* L_student;
void welcome()
{
printf("------ 图书管理系统 -----------\n");
printf("****** 1.管理员身份 **********\n");
printf("****** 2.用户身份 **********\n");
printf("****** 0.退出程序 **********\n");
printf("---------------------------------\n");
}
//创建链表
void CreateList_book()
{
L_book = (LinkList_book*)malloc(sizeof(LinkList_book));
L_book->next = NULL;
}
void CreateList_student()
{
L_student = (LinkList_student*)malloc(sizeof(LinkList_student));
L_student->next = NULL;
}
//链表的插入
void insert_book(Book book)
{
LinkList_book* p = NULL;
p = (LinkList_book*)malloc(sizeof(LinkList_book));
//Book book = { name, book_number, price, num};//?
//Book book;
strcpy(p->data.name, book.name);
strcpy(p->data.number, book.number);
p->data.price = book.price;
p->data.num = book.num;
p->data.num_comment = 0;
p->data.num_student = 0;
//p->data = book;
LinkList_book* q = NULL;
q = L_book;
while (q->next != NULL)
{
q = q->next;
}
p->next = q->next;
q->next = p;
}
void insert_student(Student student)
{
LinkList_student* p = NULL;
p = (LinkList_student*)malloc(sizeof(LinkList_student));
//account = rand();//随机分配一个账户
/* while (1)
{
account = rand();
if (Find_student(account) == NULL)
{
break;
}
}*/
//Student student = { temp_account, password, name, student_number, 0 };//?
//Student student;
p->data.student.account = student.student.account;
strcpy(p->data.student.password, student.student.password);
strcpy(p->data.student.name, student.student.name);
strcpy(p->data.student.student_number, student.student.student_number);
p->data.num_book = 0;
p->data.num_commnet = 0;
p->data.num_student = 0;
//p->data = student;
LinkList_student* q = NULL;
q = L_student;
while (q->next != NULL)
{
q = q->next;
}
p->next = q->next;
q->next = p;
}
//根据账号查找
LinkList_student* Find_student(int account)
{
LinkList_student* p = NULL;
p = L_student->next;
while (p != NULL)
{
if (p->data.student.account == account)
{
break;
}
p = p->next;
}
return p;
}
//根据图书名字查找
LinkList_book* Find_book(char name[])
{
LinkList_book* p = NULL;
p = L_book->next;
while (p != NULL)
{
if (strcmp(p->data.name, name) == 0)
{
break;
}
p = p->next;
}
return p;
}
Book Find_comment(char comment[])//查找评论所在的书籍
{
int i = 0;
LinkList_book* p = NULL;
p = L_book->next;
while (p != NULL)
{
for (i = 0; i < p->data.num_comment; i++)
{
if (strcmp(p->data.comment[i].data, comment) == 0)
{
break;
}
}
p = p->next;
}
return p->data;
}
//打印单本书
void DispBook(LinkList_book* book)
{
char name[] = "书名";
char number[] = "编号";
char price[] = "价格";
char num[] = "数量";
printf("%-16s%-16s%-16s%s\n", name, number, price, num);
printf("%-16s%-16s%-16f%-16d\n", book->data.name,
book->data.number, book->data.price, book->data.num);
}
//打印所有图书
void Disp_Book()
{
LinkList_book* temp_book = L_book->next;
while (temp_book != NULL)
{
DispBook(temp_book);
temp_book = temp_book->next;
}
}
//删除书
int Delete_book(char name[])
{
LinkList_book* p = NULL, * q = NULL;
p = L_book;
q = p->next;
int flag = 0;
while (q != NULL)
{
if (strcmp(q->data.name, name) == 0)
{
p->next = q->next;
free(q);
flag = 1;
break;
}
p = p->next;
q = p->next;
}
return flag;
}
//删除学生账号
int Delete_student(char name[])
{
int flag = 0;
LinkList_student* p = NULL, * q;
q = p = L_student->next;
while (p != NULL)
{
if (strcmp(p->data.student.name, name) == 0)
{
p->next = q->next;
free(q);
flag = 1;
break;
}
p = p->next;
q = p->next;
}
return flag;
}
//按照价格图书排序
void Sort_book()
{
LinkList_book* temp_book = L_book;//复制单链表
LinkList_book* p = NULL, * q = NULL, * r = NULL;//使用两个指针
r = temp_book;
while (p != NULL && q != NULL)
{
p = r->next;
q = p->next;
if (p->data.price > q->data.price)
{
p->next = q->next;
q->next = p;
r->next = q;
}
r = p;
DispBook(r);
}
}
//文件写操作
void saveInfoToFile_book(const char* FileName)//书
{
FILE* pf = fopen(FileName, "w");
LinkList_book* pMove = L_book->next;
while (pMove != NULL)
{
//fwrite(&pMove, sizeof(Book), 1, pf);
fwrite(&pMove->data, sizeof(Book), 1, pf);
pMove = pMove->next;
}
fclose(pf);
pf = NULL;
}
void saveInfoToFile_student(const char* FileName)
{
FILE* pf = fopen(FileName, "w");
LinkList_student* pMove = L_student->next;
while (pMove != NULL)
{
//fwrite(&pMove, sizeof(Student), 1, pf);
fwrite(&pMove->data, sizeof(Student), 1, pf);
pMove = pMove->next;
}
fclose(pf);
pf = NULL;
}
//文件读操作
void readInfoToFile_book(const char* FileName)
{
FILE* pf = fopen(FileName, "r");
if (pf == NULL)
{
pf = fopen(FileName, "w+");
}
//LinkList_book* pMove = NULL;
Book book;
//while (fread(&pMove, sizeof(Book), 1, pf) != 0)
while (1)
{
/*pMove = (LinkList_book*)malloc(sizeof(LinkList_book));
insert_book(pMove->data.name, pMove->data.number, pMove->data.price, pMove->data.num);*/
if (fread(&book, sizeof(Book), 1, pf) != 1)
break;
insert_book(book);
}
fclose(pf);
pf = NULL;
}
void readInfoToFile_student(const char* FileName)
{
FILE* pf = fopen(FileName, "r");
if (pf == NULL)
{
pf = fopen(FileName, "w+");
}
//LinkList_student* pMove = NULL;
Student student1;
//while (fread(&pMove, sizeof(Book), 1, pf) != 0)
while (1)
{
/*pMove = (LinkList_student*)malloc(sizeof(LinkList_student));
insert_student(pMove->data.password, pMove->data.name, pMove->data.student_number, pMove->data.account);*/
if (fread(&student1, sizeof(Student), 1, pf) != 1)
break;
insert_student(student1);
}
fclose(pf);
pf = NULL;
}
void DispComment_book(Book book)
{
int i = 0;
printf("========该书共有%d条评论=======\n");
for (i = 0; i < book.num_comment; i++)
{
printf("%5s%s\n%s\n", book.comment[i].student.name, book.comment[i].time, book.comment[i].data);
}
}
void DispComment_student(Student student)
{
int i = 0;
Book temp_book;
for (i = 0; i < student.num_commnet; i++)
{
temp_book = Find_comment(student.comment[i].data);
printf("《%s》%s\n%s", temp_book.name, student.comment[i].time, student.comment[i].data);
}
}
Libralian.cpp
#include"Library.h"
extern LinkList_book* L_book;
extern LinkList_student* L_student;
void LibrarianMenu()//管理员菜单
{
printf("------- 管理员界面 ---------\n");
printf("****** 1.注册新图书 **********\n");
printf("****** 2.查看已存图书 *******\n");
printf("****** 3.修改已有图书 *******\n");
printf("****** 4.注销现存图书 *******\n");
printf("****** 0.返回上一层 *********\n");
printf("---------------------------------\n");
}
void Librarian()
{
int input = 0;
int ret = 0;
do
{
LibrarianMenu();
printf("请输出0-4:>");
scanf("%d", &input);
LinkList_book* temp_book = NULL;//临时书本
char temp_name[MAX];//临时书本名
char temp_number[MAX];//临时书本编号
double temp_price;//临时书本价格
int temp_num;//临时书本数量
int temp;//临时选项
switch (input)
{
case 1:
printf("--------【注册新图书】---------\n");
printf("书名:>");
scanf("%s", temp_book->data.name);
printf("\n编号:>");
scanf("%s", temp_book->data.number);
printf("\n价格:>");
scanf("%lf", &temp_book->data.price);
printf("\n数量:>");
scanf("%d", &temp_book->data.num);
printf("\n");
insert_book(temp_book->data);
saveInfoToFile_book("book.txt");
break;
case 2:
printf("--------【查看已存图书】---------\n");
Disp_Book();
break;
case 3:
printf("--------【修改已有图书】---------\n");
printf("请输入需要修改书本的名字:>");
scanf("%s", temp_name);
printf("\n");
temp_book = Find_book(temp_name);
if (temp_book == NULL)
{
printf("该图书尚未注册\n");
}
else
{
printf("-----------------------\n");
printf("********1.书名*********\n");
printf("********2.编号*********\n");
printf("********3.价格*********\n");
printf("********4.数量*********\n");
printf("请选择需要修改的选项:>");
scanf("%d", &temp);
switch (temp)
{
case 1:
printf("修改后的书名:>");
scanf("%s", temp_name);
strcpy(temp_book->data.name, temp_name);
break;
case 2:
printf("修改后的编号:>");
scanf("%s", temp_number);
strcpy(temp_book->data.number, temp_number);
break;
case 3:
printf("修改后的价格:>");
scanf("%lf", &temp_price);
temp_book->data.price = temp_price;
break;
case 4:
printf("修改后的数量:>");
scanf("%lf", &temp_num);
temp_book->data.num = temp_num;
break;
}
}
saveInfoToFile_book("book.txt");
break;
case 4:
printf("--------【注销现存图书】---------\n");
printf("请输入要删除的书名:>");
scanf("%s", temp_name);
ret = Delete_book(temp_name);
if (ret == 1)
{
printf("-----删除成功《%s》-----\n", temp_name);
saveInfoToFile_book("book.txt");
}
else
{
printf("-----删除失败-----\n");
}
break;
case 0:
printf("-----------返回上一层------------\n");
input = 0;
break;
default:
printf("输入有误,请输入0-4间的数字\n");
break;
}
} while (input);
}
User.cpp:
#include"Library.h"
extern LinkList_book* L_book;
extern LinkList_student* L_student;
char temp_name[MAX];
Comment temp_comment;
LinkList_book* temp_book;
char choice = 0;//功能里的其他选择临时变量
void UserMenu()//用户菜单
{
printf("------ 用户界面 ----------\n");
printf("****** 1.登录 **********\n");
printf("****** 2.注册 *******\n");
printf("****** 0.返回上一层 **********\n");
printf("---------------------------------\n");
}
void UserMenu2()
{
printf("------ 用户使用界面 ---------\n");
printf("****** 1.查找图书 **********\n");
printf("****** 2.查看已存图书 *******\n");
printf("****** 3.借阅图书 *******\n");
printf("****** 4.归还图书 *******\n");
printf("****** 5.按照价格图书排序*******\n");
printf("****** 6.写评论 *******\n");
printf("****** 7.查看我的评论 *******\n");
printf("****** 0.返回上一层 **********\n");
printf("---------------------------------\n");
}
void seekBook()
{
printf("--------【查找图书】---------\n");
printf("请输入需要查找的图书名:>");
scanf("%s", temp_name);
temp_book = Find_book(temp_name);
if (temp_book != NULL)
{
DispBook(temp_book);
}
else
{
printf("没有找到该图书\n");
}
printf("是否查看《%s》评论?y/n:>", temp_name);
scanf("%c", &choice);
if (choice == 'y')
{
printf("=========该书共有%d条评论=======\n");
DispComment_book(temp_book->data);
}
}
void Register(LinkList_student* student)
{
int input;
do
{
UserMenu2();
printf("请输入0-5:>");
scanf("%d", &input);
switch (input)
{
case 1:
seekBook();
break;
case 2:
printf("--------【查看已存图书】---------\n");
Disp_Book();
break;
case 3:
printf("--------【借阅图书】---------\n");
printf("请输入要借阅图书的名字:>");
scanf("%s", temp_name);
temp_book = Find_book(temp_name);
if (temp_book != NULL)
{
student->data.book[student->data.num_book++] = temp_book->data;//学生借的书本数量+1
temp_book->data.num--;//图书馆里书本数量少1
}
else
{
printf("该图书尚且还未注册\n");
}
saveInfoToFile_book("book.txt");
break;
case 4:
printf("--------【归还图书】---------\n");
printf("请输入要归还图书的名字:>");
scanf("%s", temp_name);
temp_book = Find_book(temp_name);
if (temp_book != NULL)
{
student->data.num_book--;
Delete_book(temp_name);
}
else
{
printf("您还未借过该本书\n");
}
saveInfoToFile_book("book.txt");
break;
case 5:
printf("--------【按照价格图书排序】---------\n");
Sort_book();
break;
case 6:
printf("--------【评论】---------\n");
printf("请输入需要评论的书籍:>");
scanf("%s", temp_name);
temp_book = Find_book(temp_name);
if (temp_book != NULL)
{
printf("请输入你的评论:>");
scanf("%s", temp_comment.data);
time(&temp_comment.timep);
strcpy(temp_comment.time,asctime(gmtime(&temp_comment.timep)));//字符串复制用strcpy
temp_book->data.comment[temp_book->data.num_comment++] = temp_comment;
printf("====成功写入评论====\n");
}
else
{
printf("==========该书尚未注册=======\n");
}
break;
case 7:
printf("--------【查看我的评论 】---------\n");
printf("======我共有%d条评论========\n", student->data.num_commnet);
DispComment_student(student->data);
break;
case 0:
printf("-----------返回上一层------------\n");
input = 0;
break;
default:
printf("输入有误,请输入0-5间的数字\n");
break;
}
} while (input);
}
void User()
{
int input;
int account;
LinkList_student* temp = NULL;//
do
{
UserMenu();
printf("请输入0-2:>");
scanf("%d", &input);
switch (input)
{
//{
case 1://登录
//LinkList_student * temp = NULL;//
int account;//储存用户的账号
char password[MAX];//储存用户的密码
printf("--------【登录界面】---------\n");
printf("请输入账号和密码:\n");
printf("账号:>");
scanf("%d", &account);
temp = Find_student(account);
if (temp == NULL)//未找到该账户
{
char ret = 0;
printf("该用户不存在,是否注册,不注册则返回上一层:y/n:>");
scanf(" %c", &ret);/////////////////////////////////////////
if (ret == 'n')
{
break;
}
printf("\n");
}
else//找到了
{
while (1)
{
printf("密码:>");
scanf("%s", password);
if (strcmp(password, temp->data.student.password) == 0)
{
printf("============登录成功==============\n");
Register(temp);
break;
}
else
{
printf("\n密码错误,请重新输入:>\n");
}
}
break;
}
//}
case 2:
printf("--------【注册界面】---------\n");
while (1)
{
account = rand();
if (Find_student(account) == NULL)
{
break;
}
}
//char temp_password[MAX];
printf("请设置密码:>");
scanf("%s", temp->data.student.password);
//char temp_name[MAX];
printf("\n请输入姓名:>");
scanf("%s", temp->data.student.name);
//char temp_student_number[MAX];
printf("\n请输入学号:>");
scanf("%s", temp->data.student.student_number);
insert_student(temp->data);
printf("\n注册成功,你的账号为:%d\n", account);
saveInfoToFile_student("student.txt");
break;
case 0:
printf("-----------返回上一层------------\n");
input = 0;
break;
default:
printf("输入有误,请输入0-2间的数字\n");
break;
}
} while (input);
}
test.cpp
#include"Library.h"
LinkList_book* L_book;
LinkList_student* L_student;
int main()
{
CreateList_book();
CreateList_student();
readInfoToFile_book("book.txt");
readInfoToFile_student("student.txt");
srand((unsigned int)time(NULL));
int input = 0;// 控制用户的输入的变量
do
{
welcome();//进入菜单
printf("请选择0-2:>");
scanf("%d", &input);//用户选择
switch (input)
{
case 1://选择管理员
Librarian();//进入管理员界面
break;
case 2://选择用户
User();//进入用户界面
break;
case 0:
printf("退出程序\n");
break;
default:
printf("输入有误,请输入0-2间的数字\n");
break;
}
//system("cls");
} while (input);//输入为0自动退出
return 0;
}
LinkList_book* temp_book = NULL; 这个空指针没有分配空间啊,后面scanf自然就崩溃了