A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© acdd112 中级黑马   /  2015-11-28 00:09  /  1455 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 acdd112 于 2015-11-28 09:11 编辑

自己写了个基于链表的通讯录, 算是学完C语言后的自我检测因为将每个函数都写在了单独的一个文件, 所以就分开展示代码
  1. #ifndef Header_h
  2. #define Header_h

  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "doAdd.h"
  6. #include "doDelete.h"
  7. #include "doUpdate.h"
  8. #include "doList.h"
  9. #include "doSearch.h"
  10. #include "init.h"
  11. #include "input.h"
  12. #include "writeFile.h"


  13. #define NAMELEN 22              //姓名最大长度
  14. #define TELLEN 12               //电话最大长度
  15. #define STRULEN sizeof(Contact) //结构体大小
  16. #define filePath "telbook.data" //数据存储位置



  17. /**
  18. *  定义联系人结构体指针类型
  19. */
  20. typedef struct Person{
  21.     char name[NAMELEN];     //联系然姓名
  22.     char telnum[TELLEN];    //联系人电话
  23.     struct Person *next;    //链接下一个结构体
  24.    
  25. }Contact;

  26. extern char fno;
  27. extern int tatolContactCount;
  28. extern char BUFFER[];

  29. extern Contact *head;
  30. extern Contact *tail;
  31. extern Contact *location;
  32. extern Contact *delete;


  33. #endif /* Header_h */
复制代码

  1. #include <stdio.h>
  2. #include "Header.h"

  3. int tatolContactCount = 0;  //记录联系人总个数
  4. char fno = 0;               //用户指令
  5. char BUFFER[100];           //输入缓冲

  6. Contact *head = NULL;       //链表头指针
  7. Contact *tail = NULL;       //链表尾指针
  8. Contact *location = NULL;   //链表定位指针
  9. Contact *delete = NULL;     //链表删除指针

  10. int main(int argc, const char * argv[]) {
  11.    
  12.     init();                 //数据初始化
  13.    
  14.     printf("****************************\n");
  15.     printf("****** 欢迎使用通讯录 ******\n");
  16.     printf("****** 1. 添加联系人  ******\n");
  17.     printf("****** 2. 删除联系人  ******\n");
  18.     printf("****** 3. 修改联系人  ******\n");
  19.     printf("****** 4. 查询所有联系人  **\n");
  20.     printf("****** 5. 搜索联系人  ******\n");
  21.     printf("****** 6. 退出系统    ******\n");
  22.     printf("****************************\n");
  23.     printf("输入任意键载入系统...\n");
  24.     fgets(BUFFER, 10, stdin);
  25.     system("clear");
  26.    
  27.     //输入主入口
  28.     while (1) {
  29.         input();
  30.     }
  31.    
  32.     return 0;
  33.    
  34. }
复制代码
  1. #include "init.h"
  2. #include "Header.h"
  3. /**
  4. 初始化函数

  5. - returns: 0 初始化成功
  6. */
  7. int init()
  8. {
  9.     FILE *fp = fopen(filePath, "r");      //文件指针初始化打开数据文件
  10.     Contact *new = NULL;            //链表指针初始化
  11.     //判断是否打开数据文件
  12.     if (fp) {
  13.         //读取文件中的联系人计数
  14.         fread(&tatolContactCount, sizeof(tatolContactCount), 1, fp);
  15.    
  16.         //遍历数据文件
  17.         for (int i = 0; i < tatolContactCount; i++) {
  18.             new = (Contact *)malloc(STRULEN);   //获取新内存空间
  19.             fread(new, STRULEN, 1, fp);         //将数据文件读入内存
  20.             if (head == NULL) {
  21.                 head = tail = new;              //初始化头指针及尾指针
  22.             }
  23.             else {
  24.                 tail->next = new;               //将数据接入链表
  25.                 tail = new;                     //尾指针后移
  26.                 new->next = NULL;               
  27.             }
  28.         }
  29.         printf("通讯录初始化完成!\n");
  30.         
  31.         
  32.     }
  33.     else
  34.     {
  35.         fp = fopen(filePath, "wb");             //创建数据文件
  36.         fwrite(&tatolContactCount, sizeof(tatolContactCount), 1, fp); //写入联系人总人数
  37.         printf("通讯录文件创建成功!\n");
  38.     }
  39.    
  40.     fclose(fp);                                 //关闭文件指针
  41.     return 0;
  42. }
复制代码
  1. #include "writeFile.h"
  2. #include "Header.h"
  3. /**
  4. *  文本输入函数
  5. *
  6. *  @return 0 正常退出
  7. */
  8. int writeFile()
  9. {
  10.     FILE *fp = fopen(filePath, "wb");         //以二进制写的形式打开文本
  11.     location = head;                    //将定位指针移至表头
  12.     fwrite(&tatolContactCount, sizeof(tatolContactCount), 1, fp); //将联系人总数写至文件头
  13.     //遍历链表, 将链表内容写入数据文件
  14.     while (location) {
  15.         fwrite(location, STRULEN, 1, fp);
  16.         location = location->next;
  17.     }
  18.    
  19.     fclose(fp);                         //关闭文件指针
  20.     return 0;
  21. }
复制代码

  1. /**
  2. *  功能选择函数
  3. *  1.添加
  4. *  2.删除
  5. *  3.修改
  6. *  4.查询所有
  7. *  5.搜索
  8. *  6.退出
  9. */
  10. void input()
  11. {
  12.     printf("1.添加\t2.删除\t3.修改\t4.查询所有  5.搜索\t6.退出\n");
  13.     char name[NAMELEN];                 //记录搜索名
  14.    
  15.     printf("请选择1~6之间的功能编号:\n");
  16.     scanf("%c", &fno);
  17.     fgets(BUFFER, 10, stdin);           //输入缓冲
  18.    
  19.     switch (fno) {
  20.         case '1':
  21.                                         //执行添加
  22.             printf("请输入联系人姓名:\n");
  23.             scanf("%21s",name);
  24.             fgets(BUFFER, 10, stdin);
  25.             doAdd(name);
  26.             break;
  27.             
  28.         case '2':
  29.                                         //执行删处
  30.             printf("请输入要删除的联系人姓名:\n");
  31.             scanf("%21s", name);
  32.             fgets(BUFFER, 10, stdin);
  33.             doDelete(name);
  34.             break;
  35.             
  36.         case '3':
  37.                                         //执行修改
  38.             printf("请输入要修改的联系人姓名:\n");
  39.             scanf("%21s", name);
  40.             fgets(BUFFER, 10, stdin);
  41.             doUpdate(name);
  42.             break;
  43.             
  44.         case '4':
  45.                                         //执行查看
  46.             doList();
  47.             break;
  48.             
  49.         case '5':
  50.                                         //执行搜索
  51.             printf("请输入查找人姓名:\n");
  52.             scanf("%21s", name);
  53.             fgets(BUFFER, 10, stdin);
  54.             if(!doSearch(name)){
  55.                 /**
  56.                  *  当搜索成功, 继续可选操作
  57.                  *  1.修改 2.删除 3.返回
  58.                  */
  59.                 printf("1.修改\t2.删除\t3.返回\n");
  60.                 scanf("%c", &fno);
  61.                 fgets(BUFFER, 10, stdin);
  62.                 switch(fno){
  63.                     case '1':
  64.                         doUpdate(name);
  65.                         break;
  66.                     case '2':
  67.                         doDelete(name);
  68.                         break;
  69.                     default:
  70.                         break;
  71.                 }
  72.             }
  73.             
  74.             break;
  75.             
  76.         case '6':
  77.             printf("程序正在退出...\n");      //执行退出
  78.             printf("程序已退出!\n");
  79.             exit(0);
  80.             
  81.         default:
  82.             printf("ERROR! 请重新输入!\n");  //输入出错
  83.             break;
  84.     }
  85. }
复制代码
  1. #include "doAdd.h"
  2. #include "Header.h"
  3. /**
  4. *  联系人添加函数
  5. *
  6. *  @param name 被添加联系人的姓名
  7. */
  8. void doAdd(char name[]){
  9.     //获取新联系人的内存空间
  10.     Contact *new = NULL;
  11.     new = (Contact *)malloc(STRULEN);
  12.    
  13.     //判断内存空间否获取成功
  14.     if (new != NULL) {                  //当内存空间获取成功
  15.         //存入联系人信息
  16.         strcpy(new->name,name);
  17.         printf("请输入联系人电话:\n");
  18.         scanf("%11s",new->telnum);
  19.         getchar();
  20.         new->next = NULL;
  21.         
  22.         tatolContactCount++;            //联系人计数累加
  23.         
  24.         //判断添加的联系人是否为第一组信息
  25.         if (head == NULL) {             //当数据为第一组信息
  26.         
  27.             tail = head = new;          //初始定位头指针和尾指针
  28.         }
  29.         else                            //当数据不为第一组信息
  30.         {
  31.             tail->next = new;           //将数据添加在链表尾部
  32.             tail = new;                 //重新定位尾指针
  33.         }
  34.         writeFile();                    //保存数据
  35.         printf("联系人添加成功\n\n");
  36.         
  37.         
  38.     }
  39.     else                                //当内存空间获取失败
  40.     {
  41.         printf("ERROR!添加失败!\n\n");
  42.     }
  43. }
复制代码


1 个回复

倒序浏览
本帖最后由 acdd112 于 2015-11-28 09:01 编辑
  1. /**
  2. *  联系人删除函数
  3. *
  4. *  @param name 被删除联系人的姓名
  5. */
  6. void doDelete(char name[]){
  7.     location = head;                              //定位指针初始化
  8.     delete = head;                                //删除指针初始化
  9.     //删除指针遍历整个链表
  10.     while (delete) {
  11.         //判断是否存在联系人的姓名
  12.         if (!strcmp(name, delete->name)) {        //当前找到该联系人
  13.             tatolContactCount--;                  //联系人计数减一

  14.             if (delete == head) {                 //当联系人为链表首
  15.                 head = head->next;                //将头指针后移
  16.                 free(delete);                     //释放被删除联系人的内存空间
  17.                 writeFile();                      //保存数据
  18.                 printf("删除成功!\n\n");
  19.                 return;
  20.             }
  21.             else if (delete == tail) {            //当该联系人为链表尾
  22.                 tail = location;                  //将尾指针前移
  23.                 tail->next = NULL;
  24.                 free(delete);                     //释放被删除联系人的内存空间
  25.                 writeFile();                      //保存数据
  26.                 printf("删除成功!\n\n");
  27.                 return;
  28.             }
  29.             else {                                //当联系人在链表内部
  30.                 location->next = delete->next;    //将被删除联系人下一组信息接在其上一组信息尾部
  31.                 free(delete);                     //释放被删除联系人的内存空间
  32.                 writeFile();                      //保存数据
  33.                 printf("删除成功\n\n");
  34.                 return;
  35.             }
  36.             
  37.             
  38.         }
  39.         else {                                    //当前未找到该信息人
  40.             location = delete;                    //后移定位指针(定位指针指向删除指针前一组信息)
  41.             delete = delete->next;                //后移删除指针
  42.         }
  43.     }
  44.     printf("删除失败!未找到该联系人!\n\n");           //在链表内未找到被删除联系人信息 提示失败
  45.    
  46. }
复制代码

  1. #include "doList.h"
  2. #include "Header.h"
  3. /**
  4. *  查询所有联系人函数
  5. */
  6. void doList(){
  7.     //判断通讯录内是否有数据
  8.     if (head) {                                     //当存在数据
  9.         location = head;                            //初始化定位指针
  10.         printf("联系人\t\t电话\n");
  11.         while (location) {                          //遍历链表输出
  12.             printf("%s\t\t%s\n", location->name, location->telnum);
  13.             location = location->next;
  14.         }
  15.         printf("\n");
  16.     }
  17.     else                                            //当不存在数据
  18.     {
  19.         printf("通讯录为空!\n\n");
  20.     }
  21. }
复制代码
  1. #include "doSearch.h"
  2. #include "Header.h"
  3. /**
  4. *  联系人搜索函数
  5. *
  6. *  @param name 被搜索联系人姓名
  7. */
  8. int doSearch(char name[]){
  9.     location = head;                            //初始化定位指针
  10.     //遍历链表
  11.     while(location) {
  12.         //判断是否找到该联系人
  13.         if (! strcmp(name, location->name)) {   //当前找到该联系人
  14.             printf("联系人\t\t电话\n");           //输出该联系人信息
  15.             printf("%s\t\t%s\n", name, location->telnum);
  16.             
  17.             return 0;
  18.         }
  19.         else                                    //当前未找到该联系人
  20.         {
  21.             location = location->next;          //后移定位指针
  22.         }
  23.     }
  24.     printf("未找到您查找的联系人!\n");             //在连表内为找到该联系人 提示
  25. LOOP:
  26.     printf("是否要添加该联系人? Y/N");             //提示是否添加该联系人
  27.     scanf("%c",&fno);
  28.     fgets(BUFFER, 10, stdin);                   //输入缓冲
  29.     switch (fno) {
  30.         case 'y':
  31.         case 'Y':
  32.             doAdd(name);                        //添加新联系人
  33.             return 1;
  34.             
  35.         case 'n':
  36.         case 'N':
  37.             return 1;                              //退出
  38.             
  39.         default:
  40.             printf("输入错误!\n");
  41.             goto LOOP;                          //输入错误 跳转重新输入
  42.             break;
  43.     }
  44. }
复制代码
  1. #include "doUpdate.h"
  2. #include "Header.h"
  3. /**
  4. *  联系人修改函数
  5. *
  6. *  @param name 被修改联系人姓名
  7. */
  8. void doUpdate(char name[]){
  9.     if (doSearch(name))                         //搜索该联系人
  10.         return;                                 //当未找到则退出
  11.    
  12. LOOP:                                           //修改功能选择 1.姓名 2.电话
  13.     printf("请选择:\t1.修改联系人姓名\t2.修改联系人电话\n");
  14.     scanf("%c", &fno);
  15.     fgets(BUFFER, 10, stdin);
  16.    
  17.     switch (fno) {
  18.         case '1':
  19.                                                 //修改姓名
  20.             printf("请输入新的姓名:\n");
  21.             scanf("%21s", location->name);
  22.             fgets(BUFFER, 10, stdin);
  23.             writeFile();                        //保存数据
  24.             printf("修改成功\n\n");
  25.             break;
  26.         case '2':
  27.                                                 //修改电话
  28.             printf("请输入新的电话:\n");
  29.             scanf("%11s", location->telnum);
  30.             fgets(BUFFER, 10, stdin);
  31.             writeFile();                        //保存数据
  32.             printf("修改成功\n\n");
  33.             break;
  34.         default:
  35.                                                 //输入错误 跳转重新输入
  36.             printf("输入错误!\n");
  37.             goto LOOP;
  38.             break;
  39.     }
  40.    
  41. }
复制代码

做的还不是很完善, 欢迎大家一起学习交流
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马