1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define LEN sizeof(struct address_list) 5 6 /* 7 *************************通讯录结构体*********************************** 8 */ 9 10 struct address_list 11 { 12 char name[30]; //姓名 13 char job[30]; //工作 14 char telNO[30]; //手机号 15 char email[30]; //电子邮件 16 char address[30];//通讯地址 17 struct address_list* next; 18 19 }; 20 //函数的声明 21 struct address_list* creat(); // 调用creat()函数完成创建 22 void print(struct address_list*head); // 调用print()函数进行输出 23 struct address_list* sort(struct address_list*head); //调用sort()函数按人名进行排序 24 struct address_list* menu(struct address_list*head); //调用menu()综合操作 25 void search(struct address_list*head); //调用search()函数根据姓名进行查找。 26 struct address_list* release(struct address_list *head); //用release()函数释放内存 27 struct address_list* delete_List(struct address_list*head); //调用delete_List()函数删除通讯录 28 struct address_list* load(struct address_list*head); //调用load()函数将文件中的信息加载到链表中 29 void save(struct address_list *head); //调用save()函数将链表中的信息保存到文件中 30 struct address_list* insert(struct address_list*head); //用insert()函数增加 31 void display(struct address_list*head); //调用display()函数根据姓名进行查找 32 void showJobByName(struct address_list*head); //调用showJobByName()函数根据姓名进行查找 33 void showTelNOByName(struct address_list*head);//调用showTelByName()函数根据姓名进行查找 34 void showEmailByName(struct address_list*head);//调用showEmailByName()函数根据姓名进行查找 35 void showAddressByName(struct address_list*head);//调用showAddressByName()函数根据姓名进行查找 36 37 //全局变量 38 39 int n; //n代表通讯录中的人数 40 struct address_list *head=NULL; 41 42 /* 43 ********************主模块************************** 44 */ 45 int main() 46 { 47 48 49 char num[10]; 50 printf("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\n"); 51 printf("\t\t\t*=* 郑州大学校友通讯录 *=*\n"); 52 printf("\t\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\n"); 53 while(1) 54 { 55 printf("\t\t\t*************************************************\n"); 56 printf("\t\t\t*** 1:创建通讯录 ***\n"); 57 printf("\t\t\t*** 2:按名字排序 ***\n"); 58 printf("\t\t\t*** 3:综合操作 ***\n"); 59 printf("\t\t\t*** 4:删除 ***\n"); 60 printf("\t\t\t*** 5:保存 ***\n"); 61 printf("\t\t\t*** 6:打开 ***\n"); 62 printf("\t\t\t*** 0: 退出 ***\n"); 63 printf("\t\t\t*************************************************\n"); 64 65 //让用户进行选择要进行的操作!! 66 printf("请输入您要进行的操作:\n"); 67 gets(num); //输入用户进行的选择,按下相应的数字键即可。 68 69 switch(*num) 70 { 71 72 //创建通讯录 73 case '1': 74 { 75 if(head==NULL) 76 { //第一次进入while循环时,head是空的,以后进入添加通讯录,先释放原来的内存,再进行添加! 77 head=creat(); 78 print(head); 79 } 80 else 81 { 82 head=release(head); 83 head=creat(); 84 print(head); 85 } 86 break; 87 } 88 //按名字进行排序 89 case '2': 90 { 91 head=sort(head); 92 break; 93 } 94 //进行综合操作 95 case '3': 96 { 97 head=menu(head); 98 99 break; 100 101 } 102 //进行删除操作 103 case '4' : 104 { 105 head=delete_List(head); 106 print(head); 107 break; 108 } 109 //进行文件保存操作 110 case '5': 111 { 112 save(head); 113 print(head); 114 115 break; 116 117 } 118 //进行打开文件操作 119 case '6': 120 { 121 load(head); 122 break; 123 124 } 125 126 //退出操作 127 case '0': 128 { 129 head=release(head); 130 break; 131 } 132 default : 133 { 134 printf("输入有误,此项不存在!!"); 135 break; 136 } 137 } 138 } 139 return 0; 140 } 141 142 /* 143 *******************************创建通讯录模块*********************************** 144 创建通讯录模块的功能是实现对联系人信息的添加,它将用户输入的联系人信息存储 145 在链表中,然后返回链表的头指针。创建通讯录模块包括了creat()和print()两个函数 146 */ 147 148 /*---------------------creat()函数的代码如下:--------------------------*/ 149 struct address_list *creat() 150 { 151 struct address_list *head,*p1,*p2; 152 char name[20]; 153 n=0; 154 p1=(struct address_list *)malloc(LEN); //分给p1一个内存,里面存储的是指向address_list结构体的指针 155 p2=p1; 156 157 printf("请输入通讯录的内容\n姓名输入为0时表示创建完毕!!!!\n") ; 158 printf("请输入姓名:"); 159 160 gets(name); //输入姓名。 161 162 if(strcmp(name,"0")!=0) 163 { 164 strcpy(p1->name,name); //把输入的姓名存到链表的结点中。 165 //输入职业 166 printf("请输入职业:"); 167 gets(p1->job); 168 //输入手机号 169 printf("请输入手机号:") ; 170 gets(p1->telNO); 171 //输入电子邮件账号 172 printf("请输入电子邮件;") ; 173 gets(p1->email); 174 //输入通信地址 175 printf("请输入通信地址:") ; 176 gets(p1->address); 177 head=NULL; 178 while(1) 179 { 180 n++; //计算通信录条目数 181 if(n==1) 182 { 183 head=p1; 184 } 185 else 186 { 187 p2->next=p1; 188 } 189 p2=p1; 190 printf("请输入姓名:"); 191 gets(name); 192 if(strcmp(name,"0")==0) 193 { 194 break; 195 } 196 else 197 { 198 p1=(struct address_list *)malloc(LEN); //重新获得一个内存空间, 存储指向address_list结构体的指针 199 strcpy(p1->name,name); //把输入的姓名存到链表的结点中。 200 //输入职业 201 printf("请输入职业:"); 202 gets(p1->job); 203 //输入手机号 204 printf("请输入手机号:") ; 205 gets(p1->telNO); 206 //输入电子邮件账号 207 printf("请输入电子邮件;") ; 208 gets(p1->email); 209 //输入通信地址 210 printf("请输入通信地址:") ; 211 gets(p1->address); 212 } 213 214 215 } 216 217 p2->next=NULL; 218 return head; //返回值为链表的头指针 219 } 220 221 else 222 { 223 return NULL; 224 } 225 } 226 227 228 229 230 /******************************输出模块*******************************/ 231 232 /* 233 print()函数用来输出通讯录中的所有人的联系人信息,参数是head通讯录链表的头结点 234 */ 235 236 //**************************print函数的代码如下********************************* 237 void print(struct address_list*head) 238 { 239 if(head==NULL) 240 { 241 printf("很抱歉,您的通讯录为空,不能输出!!\n"); 242 } 243 else 244 { 245 struct address_list *p; 246 p=head; 247 printf("您的通信录中的人数为;%d\n\n",n); 248 printf("====================================================================================\n"); 249 printf("=====姓名=====工作=====手机号================电子邮件==================通讯地址=====\n"); 250 while(p!=NULL) 251 { 252 printf(" "); 253 printf("%s",p->name); //输出姓名 254 printf(" "); 255 printf("%s",p->job); //输出职业 256 printf(" "); 257 printf("%s",p->telNO); //输出电话号码 258 printf(" "); 259 printf("%s",p->email); //输出电子邮件 260 printf(" "); 261 printf("%s\n",p->address); //输出通讯地址 262 263 p=p->next; 264 } 265 printf("======================================================================================\n"); 266 } 267 } 268 269 270 /******************************排序模块****************************** 271 272 排序模块的功能是按照姓名的首字母顺序对通讯录中的联系人进行排序 273 274 */ 275 //****************************sort()函数的代码如下**************************************** 276 277 struct address_list *sort(struct address_list*head) 278 { 279 struct address_list *p1,*p2; 280 struct address_list1 281 { 282 char name[30]; //姓名 283 char job[30]; //工作 284 char telNO[30]; //手机号 285 char email[30]; //电子邮件 286 char address[30];//通讯地址 287 }; 288 289 struct address_list1 list[200]; 290 struct address_list1 tempList; 291 int i,j; 292 if(head==NULL) 293 { 294 printf("通讯录为空,不能进行排序哦~\n"); 295 return head; 296 } 297 p1=head; //把头结点赋给p1。 298 for(i=0;i<n,p1!=NULL;i++) 299 { //将当前结点的名字存到数组中 300 strcpy(list[i].name,p1->name); 301 //将当前结点的职业存到数组中 302 strcpy(list[i].job,p1->job); 303 //将当前结点的手机号存到数组中 304 strcpy(list[i].telNO,p1->telNO); 305 //将当前结点的电子邮件存到数组中 306 strcpy(list[i].email,p1->email); 307 //将当前结点的通讯地址存到数组中 308 strcpy(list[i].address,p1->address); 309 p2=p1; 310 p1=p1->next; 311 } 312 head=release(head); //释放链表空间 313 /*利用冒泡排序法,按照联系人的首字母进行排序*/ 314 for(i=0;i<n-1;i++) 315 { 316 for(j=i+1;j<n;j++) 317 { 318 if(strcmp(list[i].name,list[j].name)>0) 319 { 320 tempList=list[i]; 321 list[i]=list[j]; 322 list[j]=tempList; 323 } 324 } 325 } 326 //需要重新创建一个链表,,将排完序的联系人重新以结构体的形式存到内存中 327 /**************************创建第一个结点*******************************/ 328 p1=(struct address_list *)malloc(LEN); 329 //将数组中的第一个元素放到链表中的第一个结点中 330 strcpy(p1->name,list[0].name); 331 strcpy(p1->job,list[0].job); 332 strcpy(p1->telNO,list[0].telNO); 333 strcpy(p1->email,list[0].email); 334 strcpy(p1->address,list[0].address); 335 head=p1; 336 p2=p1; 337 for(i=1;i<n;i++) 338 { 339 p1=(struct address_list *)malloc(LEN); 340 //将数组中的其他元素放到链表中的下面结点中 341 strcpy(p1->name,list[i].name); 342 strcpy(p1->job,list[i].job); 343 strcpy(p1->telNO,list[i].telNO); 344 strcpy(p1->email,list[i].email); 345 strcpy(p1->address,list[i].address); 346 p2->next=p1; 347 p2=p1; 348 } 349 p2->next=NULL; 350 printf("按姓名排完序是;\n"); 351 print(head) ; 352 return head; 353 354 } 355 356 357 358 /**********************************综合操作模块****************************************** 359 综合操作模块可以分成几个小模块,每个小模块负责一项功能,具体可划分为查找联系人,显示单个联 360 系人信息和增加联系人三个部分。 361 在综合操作模块中先定义了menu()函数,负责整个模块的操作流程。查找联系人,显示单个联系人信息及增加 362 联系人三个小模块分别通过search()函数,display()函数和insert()函数来实现。 363 */ 364 365 /******************************menu()函数的代码如下****************************************/ 366 struct address_list* menu(struct address_list*head) 367 { 368 while(1) 369 { 370 371 printf("\t\t\t****************************************\n"); 372 printf("\t\t\t*** 1:姓名查找 ***\n"); 373 printf("\t\t\t*** 2:单个显示 ***\n"); 374 printf("\t\t\t*** 3:增加 ***\n"); 375 printf("\t\t\t*** 4:查工作 ***\n"); 376 printf("\t\t\t*** 5:查手机号 ***\n"); 377 printf("\t\t\t*** 6:查电子邮件 ***\n"); 378 printf("\t\t\t*** 7:查通讯地址 ***\n"); 379 printf("\t\t\t*** 0:退出 ***\n"); 380 printf("\t\t\t****************************************\n"); 381 382 char num[5]; 383 printf("请输入您的操作:\n"); 384 gets(num); 385 switch(*num) 386 { 387 //进行按照姓名查找具体信息。 388 case '1': 389 { 390 search(head); 391 break; 392 } 393 394 //显示单个联系人 395 case '2': 396 { 397 display(head); 398 break; 399 } 400 401 402 //增加联系人 403 case '3': 404 { 405 head=insert(head); 406 print(head); 407 break; 408 } 409 410 411 //查联系人的工作 412 case '4': 413 { 414 showJobByName(head); 415 break; 416 417 } 418 419 //查联系人的手机号 420 case '5': 421 { 422 showTelNOByName(head); 423 break; 424 } 425 426 427 //查联系人的电子邮件 428 case '6': 429 { 430 showEmailByName(head); 431 break; 432 } 433 434 435 //查联系人的通讯地址 436 case '7': 437 { 438 showAddressByName(head); 439 break; 440 } 441 442 443 //退出 444 case '0': 445 { 446 return head; 447 } 448 default : 449 { 450 printf("操作有误,请重新进行操作!!"); 451 break; 452 } 453 454 455 456 } 457 } 458 return head; 459 } 460 461 462 463 /****按照姓名查找具体信息***/ 464 //*******************************search()的代码如下******************************* 465 void search(struct address_list*head) 466 { 467 struct address_list *p1=head,*p2; 468 int m=0; 469 char *name; 470 printf("**************************\n"); 471 printf("***请输入您要查找的姓名:***\n"); 472 printf("***************************\n"); 473 gets(name); 474 if(head==NULL) 475 { 476 printf("通讯录为空,无法进行查找!!\n"); 477 } 478 while(p1!=NULL) 479 { 480 /* 481 如果输入的姓名和通讯录中的姓名相同,则数出这位联系人的详细信息。 482 */ 483 if(strcmp(p1->name,name)==0) 484 { 485 m++; 486 printf("\t\t\t=============================您要查找的联系人的信息如下===================================\n"); 487 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n"); 488 printf("\t\t\t "); 489 printf("%s",p1->name); //输出姓名 490 printf(" "); 491 printf("%s",p1->job); //输出职业 492 printf(" "); 493 printf("%s",p1->telNO); //输出手机号 494 printf(" "); 495 printf("%s",p1->email) ; //输出电子邮件 496 printf(" "); 497 printf("%s",p1->address); //输出通讯地址 498 printf("\n\n"); 499 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 500 } 501 p1=p1->next; 502 } 503 if (m==0) 504 { 505 printf("此通信录没有您查找的这位联系人!\n"); 506 } 507 printf("====="); 508 } 509 510 511 512 513 514 /****按照姓名查找具体信息***/ 515 //******************************display()的代码如下******************************* 516 517 void display(struct address_list*head) 518 { 519 struct address_list *p1=head,*p2; 520 int m=0; 521 char *name; 522 printf("**************************\n"); 523 printf("***请输入您要查找的姓名:***\n"); 524 printf("***************************\n"); 525 gets(name); 526 if(head==NULL) 527 { 528 printf("通讯录为空,无法进行查找!!\n"); 529 } 530 while(p1!=NULL) 531 { 532 533 /* 534 如果输入的姓名和通讯录中的姓名相同,则输出这位联系人的详细信息。 535 */ 536 if(strcmp(p1->name,name)==0) 537 { 538 m++; 539 540 printf("=============================您要查找的联系人的信息如下===================================\n"); 541 printf("=======姓名========职业=======手机号==========电子邮件===================通讯地址==========\n\n\n"); 542 printf(" "); 543 printf("%s",p1->name); //输出姓名 544 printf(" "); 545 printf("%s",p1->job); //输出职业 546 printf(" "); 547 printf("%s",p1->telNO); //输出手机号 548 printf(" "); 549 printf("%s",p1->email) ; //输出电子邮件 550 printf(" "); 551 printf("%s",p1->address); //输出通讯地址 552 printf("\n\n"); 553 printf("==============================================================================================\n"); 554 555 } 556 p1=p1->next; 557 558 } 559 if (m==0) 560 { 561 printf("此通信录没有您查找的这位联系人!\n"); 562 } 563 564 } 565 566 567 568 569 570 /***********增加联系人*********** 571 增加联系人功能就是将输入的联系人信息保存在链表中,添加在链表尾部。主意,按照名字首字母的顺序进行插入。 572 */ 573 //******************************insert()的代码如下******************************* 574 575 struct address_list* insert(struct address_list*head) 576 { 577 char *name; 578 struct address_list *p0,*p1,*p2; 579 printf("============================================================\n"); 580 printf("请输入您要添加联系人的姓名:"); 581 gets(name); 582 if(strcmp(name,"0")==0) 583 { 584 printf("姓名不能为空,增加失败!!\n"); 585 return head; 586 } 587 else 588 { 589 p0=(struct address_list*)malloc(LEN); //为结点分配内存,此结点用了存新添加的联系人的信息。 590 strcpy(p0->name,name); 591 printf("请输入您要添加联系人的职业:"); 592 gets(p0->job); 593 printf("请输入您要添加联系人的手机号:"); 594 gets(p0->telNO); 595 printf("请输入您要添加联系人的电子邮件:"); 596 gets(p0->email); 597 printf("请输入您要添加联系人的通信地址:"); 598 gets(p0->address) ; 599 n=n+1; //通讯录中的人数应该加一 600 } 601 602 if(head==NULL) 603 { 604 head=p0; 605 p0->next=NULL; 606 return head; 607 } 608 else 609 { 610 p1=head; 611 while(strcmp(p0->name,p1->name)>0&&p1->next!=NULL) 612 { 613 p2=p1; 614 p1=p1->next; 615 } 616 if(strcmp(p0->name,p1->name)<0||strcmp(p0->name,p1->name)==0) 617 { 618 if(head==p1) 619 { 620 head=p0; 621 p0->next=p1; 622 } 623 else 624 { 625 p2->next=p0; 626 p0->next=p1; 627 } 628 } 629 else 630 { 631 p1->next=p0; 632 p0->next=NULL; 633 } 634 return head; 635 } 636 637 } 638 639 640 641 642 643 /****按照姓名查找工作***/ 644 //******************************showJobByName()的代码如下******************************* 645 646 void showJobByName(struct address_list*head) 647 { 648 struct address_list *p1=head,*p2; 649 int m=0; 650 char *name; 651 printf("**************************\n"); 652 printf("***请输入您要查找的姓名:***\n"); 653 printf("***************************\n"); 654 gets(name); 655 if(head==NULL) 656 { 657 printf("通讯录为空,无法进行查找!!\n"); 658 } 659 while(p1!=NULL) 660 { 661 662 /* 663 如果输入的姓名和通讯录中的姓名相同,则输出这位联系人的详细信息。 664 */ 665 if(strcmp(p1->name,name)==0) 666 { 667 m++; 668 printf("\t\t\t=============================您要查找的联系人的工作如下===================================\n"); 669 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n"); 670 671 printf(" "); 672 printf("%s",p1->job); //输出职业 673 674 printf("\n\n"); 675 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 676 677 } 678 p1=p1->next; 679 680 } 681 if (m==0) 682 { 683 printf("此通信录没有您查找的这位联系人!\n"); 684 } 685 686 } 687 688 689 /****按照姓名查找手机号***/ 690 //******************************showTelNOByName()的代码如下******************************* 691 692 void showTelNOByName(struct address_list*head) 693 { 694 struct address_list *p1=head,*p2; 695 int m=0; 696 char *name; 697 printf("**************************\n"); 698 printf("***请输入您要查找的姓名:***\n"); 699 printf("***************************\n"); 700 gets(name); 701 if(head==NULL) 702 { 703 printf("通讯录为空,无法进行查找!!\n"); 704 } 705 while(p1!=NULL) 706 { 707 708 /* 709 如果输入的姓名和通讯录中的姓名相同,则输出这位联系人的详细信息。 710 */ 711 if(strcmp(p1->name,name)==0) 712 { 713 m++; 714 printf("\t\t\t=============================您要查找的联系人的手机号如下===================================\n"); 715 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n"); 716 717 printf(" "); 718 printf("%s",p1->telNO); //输出手机号 719 720 printf("\n\n"); 721 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 722 723 } 724 p1=p1->next; 725 726 } 727 if (m==0) 728 { 729 printf("此通信录没有您查找的这位联系人!\n"); 730 } 731 732 } 733 734 735 736 737 738 /****按照姓名查找电子邮件***/ 739 //******************************showEmailByName()的代码如下******************************* 740 741 void showEmailByName(struct address_list*head) 742 { 743 struct address_list *p1=head,*p2; 744 int m=0; 745 char *name; 746 printf("**************************\n"); 747 printf("***请输入您要查找的姓名:***\n"); 748 printf("***************************\n"); 749 gets(name); 750 if(head==NULL) 751 { 752 printf("通讯录为空,无法进行查找!!\n"); 753 } 754 while(p1!=NULL) 755 { 756 /* 757 如果输入的姓名和通讯录中的姓名相同,则输出这位联系人的详细信息。 758 */ 759 if(strcmp(p1->name,name)==0) 760 { 761 m++; 762 printf("\t\t\t=============================您要查找的联系人的电子邮件如下===================================\n"); 763 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n"); 764 765 printf(" "); 766 printf("%s",p1->email); //输出电子邮箱 767 768 printf("\n\n"); 769 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 770 771 } 772 p1=p1->next; 773 774 } 775 if (m==0) 776 { 777 printf("此通信录没有您查找的这位联系人!\n"); 778 } 779 780 } 781 782 783 784 785 786 787 788 /****按照姓名查找通讯地址***/ 789 //******************************showAddressByName()的代码如下******************************* 790 791 void showAddressByName(struct address_list*head) 792 { 793 struct address_list *p1=head,*p2; 794 int m=0; 795 char *name; 796 printf("**************************\n"); 797 printf("***请输入您要查找的姓名:***\n"); 798 printf("***************************\n"); 799 gets(name); 800 if(head==NULL) 801 { 802 printf("通讯录为空,无法进行查找!!\n"); 803 } 804 while(p1!=NULL) 805 { 806 807 /* 808 如果输入的姓名和通讯录中的姓名相同,则输出这位联系人的详细信息。 809 */ 810 if(strcmp(p1->name,name)==0) 811 { 812 m++; 813 printf("\t\t\t=============================您要查找的联系人的通讯地址如下===================================\n"); 814 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n"); 815 816 printf(" "); 817 printf("%s",p1->address); //输出通讯地址 818 819 printf("\n\n"); 820 printf("\t\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 821 822 } 823 p1=p1->next; 824 825 } 826 if (m==0) 827 { 828 printf("此通信录没有您查找的这位联系人!\n"); 829 } 830 831 } 832 833 834 835 836 837 /******************************保存通讯录模块********************************* 838 839 保存通讯录的功能是将通讯录的内容保存在文件中,需要遍历链表,将每个结点的 840 信息写入到文件中 。 841 */ 842 843 //*********************************save()的代码如下********************************* 844 void save(struct address_list *head) 845 { 846 FILE *fp; //定义一个指向文件的指针,文件的地址。 847 char fileName[50]; 848 struct address_list *p1; 849 850 if(head==NULL) 851 { 852 printf("通讯录为空,无法进行保存!!\n"); 853 return ; 854 } 855 else 856 { 857 printf("请输入保存后的文件名:"); 858 gets(fileName); 859 fp = fopen(fileName,"w"); 860 if(fp==NULL) 861 { 862 printf("cannot open file\n"); 863 return; 864 } 865 866 867 //将联系人的信息写入文件中。 868 p1=head; 869 fprintf(fp,"=====姓名===========职业=========手机号===============电子邮件===================通讯地址===========\n"); 870 for(;p1!=NULL;) 871 { 872 fprintf(fp,"\t\t%s %s %s %s %s \n",p1->name,p1->job,p1->telNO,p1->email,p1->address); 873 p1=p1->next; 874 } 875 printf("保存完成!!\n"); 876 fclose(fp); 877 } 878 879 880 } 881 /**********************************打开通讯录模块*********************************** 882 打开通讯录模块功能就是将文件中的内容存到内存中,建立一个链表,将联系人的信息保存到链表中 883 这是我的难点。 884 885 */ 886 //******************************load()的代码如下****************************************** 887 888 struct address_list* load(struct address_list*head) 889 { 890 FILE *fp; 891 struct address_list *p1,*p2; 892 char fileName[50]; 893 printf("请输入您要输出的文件名:"); 894 gets(fileName); 895 printf("%s\n",fileName); 896 fp=fopen(fileName,"r"); 897 if(fp==NULL) 898 { 899 printf("您要找的通讯录不存在,无法输出!\n"); 900 return head; 901 } 902 else 903 { 904 head=release(head); 905 } 906 p2=p1=(struct address_list *)malloc(LEN); 907 fscanf(fp,"%s%s%s%s%s",&p1->name,&p1->job,&p1->telNO,&p1->email,&p1->address); 908 909 //判断fp文件是否为空 910 if(feof(fp) != 0) 911 { 912 printf("文件为空,无法打开!!\n"); 913 return head; 914 } 915 else 916 { 917 918 while(!feof(fp)) 919 { 920 if(head == NULL){ 921 head = p1; 922 } 923 fscanf(fp,"%s%s%s%s%s",p1->name,p1->job,p1->telNO,p1->email,p1->address); 924 n++; 925 p2 = p1; 926 //动态分配空间 927 p1=(struct address_list*)malloc(LEN); 928 p2->next = p1; 929 } 930 p2->next=NULL; 931 free(p1); 932 p1 = head; 933 while(p1 != NULL){ 934 printf("%s\n",p1->name); 935 p1 = p1->next; 936 } 937 printf("打开完毕!\n"); 938 return head; 939 } 940 //关闭文件 941 fclose(fp); 942 } 943 944 945 946 947 948 949 950 951 952 /*********************************删除模块************************************* 953 删除模块的功能就是根据输入的姓名,在链表中逐个遍历,找到这个联系人,然后删除。 954 */ 955 956 //*********************************delete()的代码如下****************************************** 957 958 struct address_list* delete_List(struct address_list*head) 959 { 960 struct address_list *p1,*p2; 961 char *deleteName; 962 if(head==NULL) 963 { 964 printf("通讯录为空,无法删除!\n"); 965 return head; 966 } 967 printf("请输入您要删除的联系人的姓名:"); 968 gets(deleteName); //输入删除人的姓名,放到deleteName地址中 969 970 //如果要删除的联系人是链表的头结点。 971 if(strcmp(head->name,deleteName)==0) 972 { 973 head=head->next; //把下一个结点放到头结点位置上。 974 free(head); 975 n--; 976 printf("删除成功!\n"); 977 return head; 978 } 979 else 980 {//如果联系人不是头结点。 981 p1=head; 982 p2=head->next; 983 while(p2!=NULL) 984 { 985 if(strcmp(p2->name,deleteName)!=0) 986 { 987 p1=p2; 988 p2=p1->next; 989 990 } 991 if(strcmp(p2->name,deleteName)==0) 992 { 993 p1->next=p2->next; 994 free(p2); 995 printf("删除操作成功!!\n"); 996 n--; 997 return head; 998 } 999 else 1000 { 1001 printf("您要删除的这位联系人不存在!\n"); 1002 1003 } 1004 } 1005 return head; 1006 } 1007 1008 1009 } 1010 1011 1012 1013 1014 1015 1016 /********************************退出模块************************************ 1017 退出模块就是释放之前申请过的内存:链表。所以要遍历链表,然后将每个结点free掉 1018 */ 1019 //**********************release()的代码如下********************************** 1020 1021 struct address_list* release(struct address_list *head) 1022 { 1023 struct address_list *p; 1024 while(head!=NULL) 1025 { 1026 p=head; 1027 head=head->next; 1028 free(p); //释放内存 1029 } 1030 return head; //返回头指针 ,此时应为空 1031 } 1032 1033 1034 1035 1036 1037