├── BMS.c └── README.md /BMS.c: -------------------------------------------------------------------------------- 1 | //图书管理系统主界面 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | //**************常数********************* 8 | #define PENALTY 0.1//罚金0.1元一天 9 | #define DEADLINE 60//最长借书时间60天 10 | 11 | //***************定义结构体****************** 12 | struct Date//日期 13 | { 14 | int year; 15 | int month; 16 | int day; 17 | }; 18 | 19 | struct Book//书 20 | { 21 | char issn[30];//issn编号 22 | char title[30];//书名 23 | char publisher[20];//出版社 24 | char author[20];//作者 25 | double price;//价格 26 | char available;//是否借走 27 | char no[10];//被谁借走 28 | struct Book *next; 29 | }; 30 | 31 | struct History//借阅历史 32 | { 33 | char no[10];//学号 34 | char issn[30];//issn编号 35 | struct Date borrow_date;//借书时间 36 | struct Date return_date;//还书时间 37 | double penalty;//违约金 38 | struct History *next; 39 | }; 40 | 41 | struct Stu//学生 42 | { 43 | char no[10];//学号 44 | char name[10];//姓名 45 | char class_no[15];//班级 46 | char phone_number[15];//联系方式 47 | char gender;//性别 48 | struct Stu *next; 49 | }; 50 | 51 | //******************全局变量*********************** 52 | struct Stu *stu_head=NULL;//学生头指针 53 | struct Book *book_head=NULL;//书本头指针 54 | struct History *history_head=NULL;//历史头指针 55 | 56 | //************************初始化/清空数据**************************** 57 | void initialization(void) 58 | { 59 | FILE *fp; 60 | fp=fopen("stu.txt","wb"); 61 | fclose(fp); 62 | fp=fopen("book.txt","wb"); 63 | fclose(fp); 64 | fp=fopen("history.txt","wb"); 65 | fclose(fp); 66 | } 67 | //*********************读写***************************** 68 | void read_file(void);//申请内存空间并读文件 69 | void write_file(void);//写文件并释放内存空间 70 | 71 | void read_file(void)//读 72 | { 73 | FILE *fp; 74 | struct Stu *stu_p1=NULL; 75 | struct Stu *stu_p2=NULL; 76 | struct Book *book_p1=NULL; 77 | struct Book *book_p2=NULL; 78 | struct History *history_p1=NULL; 79 | struct History *history_p2=NULL; 80 | //读学生文件 81 | if((fp=fopen("stu.txt","rb"))==NULL)//打开失败重新创建 82 | fp=fopen("stu.txt","wb+"); 83 | stu_head=stu_p1=stu_p2=(struct Stu *)malloc(sizeof(struct Stu)); 84 | fread(stu_p1,sizeof(struct Stu),1,fp); 85 | while(!feof(fp)) 86 | { 87 | stu_p1=stu_p2; 88 | stu_p2=(struct Stu *)malloc(sizeof(struct Stu)); 89 | stu_p1->next=stu_p2; 90 | fread(stu_p2,sizeof(struct Stu),1,fp); 91 | } 92 | if(stu_p1==stu_p2)//文件为空 93 | stu_head=NULL; 94 | else 95 | stu_p1->next=NULL; 96 | free(stu_p2);//最后一个是无效的空间 97 | fclose(fp); 98 | //读图书文件 99 | if((fp=fopen("book.txt","rb"))==NULL)//打开失败重新创建 100 | fp=fopen("book.txt","wb+"); 101 | book_head=book_p1=book_p2=(struct Book *)malloc(sizeof(struct Book)); 102 | fread(book_p1,sizeof(struct Book),1,fp);; 103 | while(!feof(fp)) 104 | { 105 | book_p1=book_p2; 106 | book_p2=(struct Book *)malloc(sizeof(struct Book)); 107 | book_p1->next=book_p2; 108 | fread(book_p2,sizeof(struct Book),1,fp); 109 | } 110 | if(book_p1==book_p2)//文件为空 111 | book_head=NULL; 112 | else 113 | book_p1->next=NULL; 114 | free(book_p2);//最后一个是无效的空间 115 | fclose(fp); 116 | //读借阅历史文件 117 | if((fp=fopen("history.txt","rb"))==NULL)//打开失败重新创建 118 | fp=fopen("history.txt","wb+"); 119 | history_head=history_p1=history_p2=(struct History *)malloc(sizeof(struct History)); 120 | fread(history_p1,sizeof(struct History),1,fp); 121 | while(!feof(fp)) 122 | { 123 | history_p1=history_p2; 124 | history_p2=(struct History *)malloc(sizeof(struct History)); 125 | history_p1->next=history_p2; 126 | fread(history_p2,sizeof(struct History),1,fp); 127 | } 128 | if(history_p1==history_p2)//文件为空 129 | history_head=NULL; 130 | else 131 | history_p1->next=NULL; 132 | free(history_p2);//最后一个是无效的空间 133 | fclose(fp); 134 | } 135 | 136 | void write_file(void)//写 137 | { 138 | FILE *fp; 139 | struct Stu *stu_p1=NULL; 140 | struct Stu *stu_p2=NULL; 141 | struct Book *book_p1=NULL; 142 | struct Book *book_p2=NULL; 143 | struct History *history_p1=NULL; 144 | struct History *history_p2=NULL; 145 | //写学生文件 146 | fp=fopen("stu.txt","wb"); 147 | if(stu_head!=NULL)//不为空,写数据 148 | { 149 | stu_p1=stu_p2=stu_head; 150 | while(stu_p2!=NULL) 151 | { 152 | stu_p1=stu_p2; 153 | fwrite(stu_p1,sizeof(struct Stu),1,fp); 154 | stu_p2=stu_p1->next; 155 | } 156 | } 157 | fclose(fp); 158 | //写图书文件 159 | fp=fopen("book.txt","wb"); 160 | if(book_head!=NULL)//不为空,写数据 161 | { 162 | book_p1=book_p2=book_head; 163 | while(book_p2!=NULL) 164 | { 165 | book_p1=book_p2; 166 | fwrite(book_p1,sizeof(struct Book),1,fp); 167 | book_p2=book_p1->next; 168 | } 169 | } 170 | fclose(fp); 171 | //写历史文件 172 | fp=fopen("history.txt","wb"); 173 | if(history_head!=NULL)//不为空,写数据 174 | { 175 | history_p1=history_p2=history_head; 176 | while(history_p2!=NULL) 177 | { 178 | history_p1=history_p2; 179 | fwrite(history_p1,sizeof(struct History),1,fp); 180 | history_p2=history_p1->next; 181 | } 182 | } 183 | fclose(fp); 184 | 185 | } 186 | void freeall(void)//释放空间 187 | { 188 | struct Stu *stu_p1=NULL; 189 | struct Stu *stu_p2=NULL; 190 | struct Book *book_p1=NULL; 191 | struct Book *book_p2=NULL; 192 | struct History *history_p1=NULL; 193 | struct History *history_p2=NULL; 194 | if(stu_head!=NULL)//不为空 195 | { 196 | stu_p1=stu_p2=stu_head; 197 | while(stu_p2!=NULL) 198 | { 199 | stu_p1=stu_p2; 200 | stu_p2=stu_p1->next; 201 | free(stu_p1);//释放空间 202 | } 203 | stu_head=NULL; 204 | } 205 | if(book_head!=NULL)//不为空 206 | { 207 | book_p1=book_p2=book_head; 208 | while(book_p2!=NULL) 209 | { 210 | book_p1=book_p2; 211 | book_p2=book_p1->next; 212 | free(book_p1);//释放空间 213 | } 214 | book_head=NULL; 215 | } 216 | if(history_head!=NULL)//不为空,写数据 217 | { 218 | history_p1=history_p2=history_head; 219 | while(history_p2!=NULL) 220 | { 221 | history_p1=history_p2; 222 | history_p2=history_p1->next; 223 | free(history_p1);//释放空间 224 | } 225 | history_head=NULL; 226 | } 227 | } 228 | 229 | //*****************转换大小写,并消除回车************************ 230 | char upper_getchar(void) 231 | { 232 | char ch; 233 | while (ch = toupper(getchar())) 234 | { 235 | if (ch == '\n') 236 | continue; 237 | else 238 | break; 239 | } 240 | return ch; 241 | } 242 | //**********************计算日期间间隔*************************** 243 | int datecmp(struct Date start,struct Date end) //判断日期大小是否合法 244 | { 245 | if(start.year*10000+start.month*100+start.day<=end.year*10000+end.month*100+end.day)//把日期转化为20180227的形式来比大小 246 | return 1;//正确 247 | else 248 | return -1;//错误 249 | } 250 | 251 | int cal_date(struct Date start,struct Date end)//计算日期间隔 252 | { 253 | if(datecmp(start,end)==-1) 254 | { 255 | puts("日期错误"); 256 | return -1; 257 | } 258 | else 259 | { 260 | int y1,m1,d1; 261 | int y2,m2,d2; 262 | m1 = (start.month + 9) % 12; 263 | y1 = start.year - m1/10; 264 | d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (start.day - 1); 265 | m2 = (end.month + 9) % 12; 266 | y2 = end.year- m2/10; 267 | d2 = 365*y2 + y2/4 - y2/100 + y2/400 + (m2*306 + 5)/10 + (end.day - 1); 268 | 269 | return (d2 - d1);//日期间隔 270 | } 271 | } 272 | 273 | //****************查询系统********************** 274 | void query(void);//查询系统 275 | int search_book(char issn[],struct Book **book_p1,struct Book **book_p2);//图书查询 276 | int search_stu(char no[],struct Stu **stu_p1,struct Stu **stu_p2);//学生信息查询 277 | int search_history(char no[],char issn[],struct History **history_p1,struct History **history_p2);//历史查询 278 | void return_book_now(void);//催缴图书 279 | void query(void) 280 | { 281 | struct Stu *stu_p1=NULL; 282 | struct Book *book_p1=NULL; 283 | struct History *history_p1=NULL; 284 | struct Stu *stu_p2=NULL; 285 | struct Book *book_p2=NULL; 286 | struct History *history_p2=NULL; 287 | char buffer_issn[30];//书籍issn编号 288 | char buffer_no[30];//学生学号 289 | char option; 290 | system("cls"); 291 | do 292 | { 293 | puts("************查询系统************"); 294 | puts("A.图书查询"); 295 | puts("B.学生信息查询"); 296 | puts("C.历史信息查询"); 297 | puts("D.催缴图书"); 298 | puts("Q.返回图书管理系统"); 299 | puts("请输入选项:按回车键确认,大小写均可"); 300 | switch (option = upper_getchar()) 301 | { 302 | case 'A':puts("请输入issn编号,按回车确认"); 303 | scanf("%s",buffer_issn); 304 | search_book(buffer_issn,&book_p1,&book_p2); 305 | break; 306 | case 'B':puts("请输入学号,按回车确认"); 307 | scanf("%s",buffer_no); 308 | search_stu(buffer_no,&stu_p1,&stu_p2); 309 | break; 310 | case 'C':puts("请输入学号,按回车确认"); 311 | scanf("%s",buffer_no); 312 | search_history(buffer_no,"ALL",&history_p1,&history_p2);//"ALL"代表查该学生所有 313 | break; 314 | case 'D':return_book_now(); 315 | case 'Q':break; 316 | default:puts("\n\n请输入对应操作的英文字母选项!!!"); 317 | system("Pause"); 318 | break; 319 | } 320 | system("cls"); 321 | } while (option != 'Q'); 322 | } 323 | //查询书 324 | int search_book(char issn[],struct Book **book_p1,struct Book **book_p2)//p1为前一个指针,p2是待查项指针 325 | { 326 | int flag=0;//标记找没找到,初始值0 327 | *book_p1=*book_p2=book_head; 328 | while(*book_p2!=NULL) 329 | { 330 | if(strcmp(issn,(*book_p2)->issn)==0) 331 | { 332 | flag=1; 333 | break; 334 | } 335 | *book_p1=*book_p2; 336 | *book_p2=(*book_p1)->next; 337 | } 338 | if(flag)//找到了 339 | { 340 | puts("找到此书"); 341 | printf("书名:%s issn编号:%s \n出版社:%s 作者:%s \n价格:%lf \n", 342 | (*book_p2)->title,(*book_p2)->issn, 343 | (*book_p2)->publisher,(*book_p2)->author, 344 | (*book_p2)->price); 345 | printf("被谁借走:%s\n",(*book_p2)->no); 346 | } 347 | else 348 | puts("无此记录!!!"); 349 | system("pause"); 350 | 351 | return flag; 352 | } 353 | 354 | int search_stu(char no[],struct Stu **stu_p1,struct Stu **stu_p2)//p1为前一个指针,p2是待查项指针 355 | { 356 | int flag=0;//标记找没找到,初始值0 357 | *stu_p1=*stu_p2=stu_head; 358 | while(*stu_p2!=NULL) 359 | { 360 | if(strcmp(no,(*stu_p2)->no)==0) 361 | { 362 | flag=1; 363 | break; 364 | } 365 | *stu_p1=*stu_p2; 366 | *stu_p2=(*stu_p1)->next; 367 | } 368 | if(flag)//找到了 369 | { 370 | puts("找到此学生"); 371 | printf("学号:%s 姓名:%s 班级:%s 联系方式:%s 性别:%c\n",(*stu_p2)->no,(*stu_p2)->name,(*stu_p2)->class_no, 372 | (*stu_p2)->phone_number,(*stu_p2)->gender); 373 | } 374 | else 375 | puts("无此记录!!!"); 376 | system("pause"); 377 | 378 | return flag; 379 | } 380 | 381 | int search_history(char no[],char issn[],struct History **history_p1,struct History **history_p2)//p1为前一个指针,p2是待查项指针 382 | { 383 | int flag=0;//标记找没找到,初始值0 384 | *history_p1=*history_p2=history_head; 385 | if(strcmp(issn,"ALL")==0) 386 | { 387 | while(*history_p2!=NULL) 388 | { 389 | if((strcmp(no,(*history_p2)->no)==0)) 390 | { 391 | flag=1; 392 | printf("学号:%s issn编号:%s\n借书日期:%d/%d/%d\n还书日期:%d/%d/%d\n违约金:%lf\n", 393 | (*history_p2)->no,(*history_p2)->issn, 394 | (*history_p2)->borrow_date.year,(*history_p2)->borrow_date.month,(*history_p2)->borrow_date.day, 395 | (*history_p2)->return_date.year,(*history_p2)->return_date.month,(*history_p2)->return_date.day, 396 | (*history_p2)->penalty); 397 | puts("**********************"); 398 | } 399 | *history_p1=*history_p2; 400 | *history_p2=(*history_p1)->next; 401 | } 402 | puts("**********************"); 403 | system("pause"); 404 | } 405 | else 406 | { 407 | while(*history_p2!=NULL) 408 | { 409 | if(strcmp(no,(*history_p2)->no)==0&&strcmp(issn,(*history_p2)->issn)==0&&(*history_p2)->return_date.year==0)//学号找到,书号找到,且没有还书 410 | { 411 | flag=1; 412 | break;//找到,跳出 413 | } 414 | *history_p1=*history_p2; 415 | *history_p2=(*history_p1)->next; 416 | } 417 | if(flag)//找到了 418 | { 419 | puts("找到此记录"); 420 | printf("学号:%s issn编号:%s\n借书日期:%d/%d/%d\n还书日期:%d/%d/%d\n违约金:%lf\n", 421 | (*history_p2)->no,(*history_p2)->issn, 422 | (*history_p2)->borrow_date.year,(*history_p2)->borrow_date.month,(*history_p2)->borrow_date.day, 423 | (*history_p2)->return_date.year,(*history_p2)->return_date.month,(*history_p2)->return_date.day, 424 | (*history_p2)->penalty); 425 | } 426 | else 427 | puts("无此记录!!!"); 428 | system("pause"); 429 | } 430 | return flag; 431 | } 432 | 433 | void return_book_now(void)//该还书了,催缴 434 | { 435 | struct History *history_p; 436 | struct Stu *stu_p1=NULL; 437 | struct Stu *stu_p2=NULL; 438 | struct Date date; 439 | puts("请输入今天日期"); 440 | scanf("%d%d%d",&date.year,&date.month,&date.day); 441 | history_p=history_head; 442 | while(history_p!=NULL) 443 | { 444 | if(history_p->return_date.year==0&&cal_date(history_p->borrow_date,date)>DEADLINE)//没还书且超出日期 445 | { 446 | printf("催缴:书本编号:%s 学号:%s\n",history_p->issn,history_p->no); 447 | search_stu(history_p->no,&stu_p1,&stu_p2); 448 | puts("****************************************"); 449 | } 450 | history_p=history_p->next; 451 | } 452 | system("pause"); 453 | } 454 | 455 | 456 | //***********************学生管理系统******************* 457 | void stu_management(void);//学生管理系统 458 | 459 | void add_stu(void);//添加学生 460 | void modify_stu(void);//修改学生信息 461 | void delete_stu(void);//删除学生信息 462 | void view_stu(void);//查看学生信息 463 | 464 | 465 | void stu_management(void) 466 | { 467 | char option; 468 | system("cls"); 469 | do 470 | { 471 | puts("************学生信息管理************"); 472 | puts("A.添加学生信息"); 473 | puts("B.修改学生个人信息"); 474 | puts("C.删除学生个人信息"); 475 | puts("D.查看所有学生个人信息"); 476 | puts("Q.返回图书管理系统"); 477 | puts("请输入选项:按回车键确认,大小写均可"); 478 | puts("所有信息存放在d盘下"); 479 | switch (option = upper_getchar()) 480 | { 481 | case 'A':add_stu(); break; 482 | case 'B':modify_stu(); break; 483 | case 'C':delete_stu(); break; 484 | case 'D':view_stu(); break; 485 | case 'Q':break; 486 | default:puts("\n\n请输入对应操作的英文字母选项!!!"); 487 | system("Pause"); 488 | break; 489 | } 490 | system("cls"); 491 | } while (option != 'Q'); 492 | } 493 | 494 | 495 | //添加学生前先查找是否存在重复,然后再添加 496 | void add_stu(void) 497 | { 498 | char option;//选项 499 | struct Stu *stu_p1=NULL; 500 | struct Stu *stu_p2=NULL; 501 | struct Stu stu; 502 | 503 | 504 | puts("请输入学号"); 505 | printf("学号:___________\b\b\b\b\b\b\b\b\b\b"); 506 | scanf("%s",stu.no); 507 | puts("查找中..."); 508 | if(search_stu(stu.no,&stu_p1,&stu_p2)==1)//重复了 509 | { 510 | puts("已有该学生及记录"); 511 | Sleep(1000); 512 | return; 513 | } 514 | 515 | puts("请填写该新生详细信息,按回车键录入"); 516 | 517 | printf("学号:%s\n",stu.no); 518 | printf("姓名:_______\b\b\b\b\b\b"); 519 | scanf("%s",&stu.name); 520 | puts("姓名已录入"); 521 | 522 | printf("班级:___________\b\b\b\b\b\b\b\b\b\b"); 523 | scanf("%s",&stu.class_no); 524 | puts("班级已录入"); 525 | 526 | printf("性别:____\b\b"); 527 | stu.gender=upper_getchar(); 528 | puts("性别已录入"); 529 | 530 | printf("联系方式:___________\b\b\b\b\b\b\b\b\b\b"); 531 | scanf("%s",&stu.phone_number); 532 | puts("联系方式已录入"); 533 | 534 | stu.next=NULL; 535 | 536 | puts("是否保存,输入Y/N,不区分大小写"); 537 | do 538 | { 539 | option=upper_getchar(); 540 | if(option=='Y') 541 | { 542 | stu_p2=(struct Stu *)malloc(sizeof(struct Stu)); 543 | *stu_p2=stu; 544 | system("pause"); 545 | if(stu_head==NULL)//空链表 546 | stu_head=stu_p2; 547 | else 548 | stu_p1->next=stu_p2; 549 | puts("已录入!"); 550 | Sleep(500); 551 | } 552 | }while(!(option=='Y'||option=='N'));//必须输入Y/N 553 | } 554 | 555 | //修改学生前先查找是否存在 556 | void modify_stu(void) 557 | { 558 | char option;//选项 559 | struct Stu stu; 560 | struct Stu *stu_p1=NULL; 561 | struct Stu *stu_p2=NULL; 562 | 563 | puts("请输入学号"); 564 | printf("学号:___________\b\b\b\b\b\b\b\b\b\b"); 565 | scanf("%s",&stu.no); 566 | puts("查找中..."); 567 | if(search_stu(stu.no,&stu_p1,&stu_p2)==0)//学生不存在 568 | { 569 | Sleep(1000); 570 | return; 571 | } 572 | 573 | puts("请填写详细信息,按回车键录入"); 574 | printf("姓名:_______\b\b\b\b\b\b"); 575 | scanf("%s",&stu.name); 576 | puts("姓名已录入"); 577 | printf("班级:___________\b\b\b\b\b\b\b\b\b\b"); 578 | scanf("%s",&stu.class_no); 579 | printf("班级已录入"); 580 | printf("性别:___\b\b"); 581 | stu.gender=upper_getchar(); 582 | puts("性别已录入"); 583 | printf("联系方式:___________\b\b\b\b\b\b\b\b\b\b"); 584 | scanf("%s",&stu.phone_number); 585 | puts("联系方式已录入"); 586 | puts("是否保存,输入Y/N,不区分大小写"); 587 | stu.next=stu_p2->next; 588 | do 589 | { 590 | option=upper_getchar(); 591 | if(option=='Y') 592 | { 593 | //写进去,覆盖,再输入替换 594 | *stu_p2=stu; 595 | puts("已录入!"); 596 | Sleep(500); 597 | } 598 | }while(!(option=='Y'||option=='N')); 599 | } 600 | 601 | //删除学生前,先查找是否存在 602 | void delete_stu(void) 603 | { 604 | char option;//选项 605 | struct Stu stu; 606 | struct Stu *stu_p1=NULL; 607 | struct Stu *stu_p2=NULL; 608 | puts("请输入学号"); 609 | printf("学号:___________\b\b\b\b\b\b\b\b\b\b"); 610 | scanf("%s",&stu.no); 611 | puts("查找中..."); 612 | if(search_stu(stu.no,&stu_p1,&stu_p2)==0)//学生不存在 613 | { 614 | Sleep(1000); 615 | return; 616 | } 617 | else//一旦找到了,p2指针就在要删除的学生处,p1是p2之前的 618 | { 619 | puts("是否删除?输入Y/N,不区分大小写"); 620 | do 621 | { 622 | option=upper_getchar(); 623 | if(option=='Y') 624 | { 625 | if(stu_p2==stu_head)//链表头 626 | stu_head=stu_p2->next; 627 | else 628 | stu_p1->next=stu_p2->next; 629 | free(stu_p2); 630 | puts("删除成功!"); 631 | Sleep(1000); 632 | return; 633 | } 634 | }while(!(option=='Y'||option=='N')); 635 | } 636 | } 637 | //查看学生信息 638 | void view_stu(void) 639 | { 640 | struct Stu *stu_p; 641 | stu_p=stu_head; 642 | while(stu_p!=NULL) 643 | { 644 | printf("学号:%s 姓名:%s 班级:%s 性别:%c\n",stu_p->no,stu_p->name,stu_p->class_no,stu_p->gender); 645 | printf("************************************\n"); 646 | stu_p=stu_p->next; 647 | } 648 | system("pause"); 649 | } 650 | //********************书籍管理系统***************** 651 | void book_management(void);//书籍管理系统 652 | void add_book(void);//添加新书 653 | void modify_book(void);//修改书籍信息 654 | void delete_book(void);//删除书籍信息 655 | void view_book(void);//查看图书信息 656 | 657 | void book_management(void) 658 | { 659 | char option; 660 | system("cls"); 661 | do 662 | { 663 | puts("************图书信息管理************"); 664 | puts("A.添加新图书信息"); 665 | puts("B.修改图书信息"); 666 | puts("C.删除图书"); 667 | puts("D.查看图书信息"); 668 | puts("Q.返回图书管理系统"); 669 | puts("请输入选项:按回车键确认,大小写均可"); 670 | puts("所有信息存放在d盘下"); 671 | switch (option = upper_getchar()) 672 | { 673 | case 'A':add_book(); break; 674 | case 'B':modify_book(); break; 675 | case 'C':delete_book(); break; 676 | case 'D':view_book(); break; 677 | case 'Q':break; 678 | default:puts("\n\n请输入对应操作的英文字母选项!!!"); 679 | system("Pause"); 680 | break; 681 | } 682 | system("cls"); 683 | } while (option != 'Q'); 684 | } 685 | 686 | //添加图书前先查找是否存在重复,然后再添加 687 | void add_book(void) 688 | { 689 | 690 | char option;//选项 691 | struct Book book; 692 | struct Book *book_p1=NULL; 693 | struct Book *book_p2=NULL; 694 | 695 | puts("请输入issn编号"); 696 | printf("issn编号:______________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 697 | scanf("%s",&book.issn); 698 | puts("查找中..."); 699 | if(search_book(book.issn,&book_p1,&book_p2)==1)//重复了 700 | { 701 | puts("已有该书及记录"); 702 | Sleep(1000); 703 | return; 704 | } 705 | 706 | strcpy(book.no,"无");//初始化 707 | puts("请填写该新书详细信息,按回车键录入"); 708 | printf("issn编号:%s\n",book.issn); 709 | printf("书名:_____________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 710 | scanf("%s",&book.title); 711 | puts("书名已录入"); 712 | printf("作者:____________\b\b\b\b\b\b\b"); 713 | scanf("%s",&book.author); 714 | puts("作者已录入"); 715 | printf("出版社:_____________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 716 | scanf("%s",&book.publisher); 717 | puts("出版社已录入"); 718 | printf("价格:_____\b\b\b\b"); 719 | scanf("%lf",&book.price); 720 | puts("价格已录入"); 721 | puts("是否保存,输入Y/N,不区分大小写"); 722 | book.next=NULL; 723 | do 724 | { 725 | option=upper_getchar(); 726 | if(option=='Y') 727 | { 728 | book_p2=(struct Book *)malloc(sizeof(struct Book)); 729 | *book_p2=book; 730 | if(book_head==NULL)//空链表 731 | book_head=book_p2; 732 | else 733 | book_p1->next=book_p2; 734 | puts("已录入!"); 735 | Sleep(500); 736 | } 737 | }while(!(option=='Y'||option=='N'));//必须输入Y/N 738 | } 739 | 740 | //修改图书前先查找是否存在 741 | void modify_book(void) 742 | { 743 | char option;//选项 744 | struct Book book; 745 | struct Book *book_p1=NULL; 746 | struct Book *book_p2=NULL; 747 | 748 | 749 | puts("请输入issn编号"); 750 | printf("issn编号:___________\b\b\b\b\b\b\b\b\b\b"); 751 | scanf("%s",&book.issn); 752 | puts("查找中..."); 753 | if(search_book(book.issn,&book_p1,&book_p2)==0)//学生不存在 754 | { 755 | Sleep(1000); 756 | return; 757 | } 758 | 759 | //一旦找到了,指针就在此图书信息处 760 | puts("请填写该新书详细信息,按回车键录入"); 761 | printf("issn编号:%s\n",book.issn); 762 | printf("书名:_____________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 763 | scanf("%s",&book.title); 764 | puts("书名已录入"); 765 | printf("作者:____________\b\b\b\b\b\b\b"); 766 | scanf("%s",&book.author); 767 | puts("作者已录入"); 768 | printf("出版社:_____________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 769 | scanf("%s",&book.publisher); 770 | puts("出版社已录入"); 771 | printf("价格:_____\b\b\b\b"); 772 | scanf("%lf",&book.price); 773 | puts("价格已录入"); 774 | book.available=book_p2->available;//初始化 775 | book.next=book_p2->next; 776 | puts("是否保存,输入Y/N,不区分大小写"); 777 | do 778 | { 779 | option=upper_getchar(); 780 | if(option=='Y') 781 | { 782 | //写进去,覆盖,再输入替换 783 | *book_p2=book; 784 | puts("已录入!"); 785 | Sleep(500); 786 | } 787 | }while(!(option=='Y'||option=='N')); 788 | } 789 | 790 | //删除图书前,先查找是否存在 791 | void delete_book(void) 792 | { 793 | char option;//选项 794 | struct Book book; 795 | struct Book *book_p1=NULL; 796 | struct Book *book_p2=NULL; 797 | 798 | puts("请输入issn编号"); 799 | printf("issn编号:______________________\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 800 | scanf("%s",&book.issn); 801 | puts("查找中..."); 802 | if(search_book(book.issn,&book_p1,&book_p2)==0)//图书不存在 803 | { 804 | Sleep(1000); 805 | return; 806 | } 807 | else//一旦找到了,p2指针就在要删除的图书处 808 | { 809 | puts("是否删除?输入Y/N,不区分大小写"); 810 | do 811 | { 812 | option=upper_getchar(); 813 | if(option=='Y') 814 | { 815 | if(book_p2==book_head)//链表头 816 | book_head=book_p2->next; 817 | else 818 | book_p1->next=book_p2->next; 819 | free(book_p2); 820 | puts("删除成功!"); 821 | Sleep(1000); 822 | return; 823 | } 824 | }while(!(option=='Y'||option=='N')); 825 | } 826 | } 827 | //查看图书信息 828 | void view_book(void) 829 | { 830 | struct Book *book_p; 831 | book_p=book_head; 832 | while(book_p!=NULL) 833 | { 834 | printf("书名:%s issn编号:%s \n出版社:%s 作者:%s \n价格:%lf \n", 835 | book_p->title,book_p->issn, 836 | book_p->publisher,book_p->author, 837 | book_p->price); 838 | printf("************************************\n"); 839 | book_p=book_p->next; 840 | } 841 | system("pause"); 842 | } 843 | 844 | //**********************借/还书******************** 845 | void borrow_or_return_book(void); 846 | void borrow_book(void);//借书 847 | void return_book(void);//还书 848 | 849 | void borrow_or_return_book(void) 850 | { 851 | char option; 852 | system("cls"); 853 | do 854 | { 855 | puts("************借/还书************"); 856 | puts("A.借书"); 857 | puts("B.还书"); 858 | puts("Q.返回图书管理系统"); 859 | puts("请输入选项:按回车键确认,大小写均可"); 860 | switch (option = upper_getchar()) 861 | { 862 | case 'A':borrow_book(); break; 863 | case 'B':return_book(); break; 864 | case 'Q':break; 865 | default:puts("\n\n请输入对应操作的英文字母选项!!!"); 866 | system("Pause"); 867 | break; 868 | } 869 | system("cls"); 870 | } while (option != 'Q'); 871 | } 872 | void borrow_book(void)//借书 873 | { 874 | char option;//选项 875 | struct Stu stu; 876 | struct Stu *stu_p1=NULL; 877 | struct Stu *stu_p2=NULL; 878 | 879 | struct Book book; 880 | struct Book *book_p1=NULL; 881 | struct Book *book_p2=NULL; 882 | 883 | struct History history; 884 | struct History *history_p1=NULL; 885 | struct History *history_p2=NULL; 886 | 887 | puts("请输入学号"); 888 | printf("学号:___________\b\b\b\b\b\b\b\b\b\b"); 889 | scanf("%s",&stu.no); 890 | puts("查找中..."); 891 | if(search_stu(stu.no,&stu_p1,&stu_p2)==0)//学生不存在 892 | { 893 | Sleep(1000); 894 | return; 895 | } 896 | puts("请输入图书的issn编号"); 897 | printf("issn编号:___________\b\b\b\b\b\b\b\b\b\b"); 898 | scanf("%s",&book.issn); 899 | puts("查找中..."); 900 | if(search_book(book.issn,&book_p1,&book_p2)==0)//图书不存在 901 | { 902 | Sleep(1000); 903 | return; 904 | } 905 | 906 | if(book_p2->available=='N') 907 | { 908 | puts("此图书已经被借走!"); 909 | system("pause"); 910 | return;//函数结束 911 | } 912 | search_history(stu.no,book.issn,&history_p1,&history_p2); 913 | book=*book_p2; 914 | book.available='N';//借走了 915 | strcpy(book.no,stu.no); 916 | puts("请输入借书时间"); 917 | scanf("%d%d%d",&history.borrow_date.year,&history.borrow_date.month,&history.borrow_date.day); 918 | strcpy(history.issn,book.issn); 919 | strcpy(history.no,stu.no); 920 | history.penalty=0; 921 | history.return_date.day=0; 922 | history.return_date.month=0; 923 | history.return_date.year=0; 924 | history.next=NULL; 925 | puts("是否借书,输入Y/N,不区分大小写"); 926 | do 927 | { 928 | option=upper_getchar(); 929 | if(option=='Y') 930 | { 931 | *book_p2=book; 932 | history_p2=(struct History *)malloc(sizeof(struct History)); 933 | *history_p2=history; 934 | if(history_head==NULL)//空链表 935 | history_head=history_p2; 936 | else 937 | history_p1->next=history_p2; 938 | puts("已录入!"); 939 | Sleep(500); 940 | } 941 | }while(!(option=='Y'||option=='N')); 942 | } 943 | 944 | 945 | void return_book(void) 946 | { 947 | 948 | char option;//选项 949 | struct History history; 950 | struct Book book; 951 | struct History *history_p1=NULL; 952 | struct History *history_p2=NULL; 953 | struct Book *book_p1=NULL; 954 | struct Book *book_p2=NULL; 955 | 956 | puts("请输入学号"); 957 | printf("学号:___________\b\b\b\b\b\b\b\b\b\b"); 958 | scanf("%s",&history.no); 959 | puts("请输入图书的issn编号"); 960 | printf("issn编号:___________\b\b\b\b\b\b\b\b\b\b"); 961 | scanf("%s",&history.issn); 962 | puts("查找中..."); 963 | if(search_history(history.no,history.issn,&history_p1,&history_p2)==0)//记录不存在 964 | { 965 | Sleep(1000); 966 | return; 967 | } 968 | history=*history_p2; 969 | search_book(history.issn,&book_p1,&book_p2); 970 | book=*book_p2; 971 | book.available='Y';//初始化 972 | strcpy(book.no,"无");//初始化 973 | puts("请输入还书时间"); 974 | scanf("%d%d%d",&history.return_date.year,&history.return_date.month,&history.return_date.day); 975 | if(cal_date(history.borrow_date,history.return_date)-DEADLINE>0)//超过还书日期了 976 | history.penalty=(cal_date(history.borrow_date,history.return_date)-DEADLINE)*PENALTY; 977 | else 978 | history.penalty=0; 979 | puts("是否还书,输入Y/N,不区分大小写"); 980 | do 981 | { 982 | option=upper_getchar(); 983 | if(option=='Y') 984 | { 985 | *book_p2=book; 986 | *history_p2=history; 987 | puts("已录入!"); 988 | if(history.penalty) 989 | printf("本次借书逾期!\n罚金:%lf",history.penalty); 990 | system("pause"); 991 | } 992 | }while(!(option=='Y'||option=='N')); 993 | } 994 | //*********************主函数********************* 995 | int main(void) 996 | { 997 | char option; 998 | read_file(); 999 | printf(" 欢 "); 1000 | Sleep(500); 1001 | printf("迎 "); 1002 | Sleep(500); 1003 | printf("使 "); 1004 | Sleep(500); 1005 | printf("用 "); 1006 | Sleep(500); 1007 | printf("图 "); 1008 | Sleep(500); 1009 | printf("书 "); 1010 | Sleep(500); 1011 | printf("管 "); 1012 | Sleep(500); 1013 | printf("理 "); 1014 | Sleep(500); 1015 | printf("系 "); 1016 | Sleep(500); 1017 | printf("统 "); 1018 | Sleep(500); 1019 | system("cls"); 1020 | do 1021 | { 1022 | puts("************图书管理系统************"); 1023 | puts("A.学生信息管理"); 1024 | puts("B.图书信息管理"); 1025 | puts("C.借/还书"); 1026 | puts("D.综合查询"); 1027 | puts("E.清空数据/初始化"); 1028 | puts("Q.退出"); 1029 | puts("请输入选项:按回车键确认,大小写均可"); 1030 | switch (option = upper_getchar()) 1031 | { 1032 | case 'A':stu_management(); write_file();break; 1033 | case 'B':book_management(); write_file();break; 1034 | case 'C':borrow_or_return_book();write_file(); break; 1035 | case 'D':query();break; 1036 | case 'E':freeall();initialization();break; 1037 | case 'Q':break; 1038 | default:puts("\n\n请输入对应操作的英文字母选项!!!"); 1039 | system("Pause"); 1040 | break; 1041 | } 1042 | system("cls"); //下一次操作清屏 1043 | } while (option != 'Q'); 1044 | freeall(); 1045 | for(int i=0;i<6;i++)//退出特效 1046 | { 1047 | for(int j=0;j