广州大学物理与电子工程学院程序与设计训练通讯录管理系统实验报告专业班级:电子121设计人员:元达鹏学号:**********2013年6月24日通讯录管理系统一.需求分析设计题目及需求:(1)查看功能:选择此功能时,列出下列三类选择。
A 办公类 B 个人类 C 商务类,当选中某类时,显示出此类所有数据中的姓名和电话号码)(2)增加功能:能录入新数据(一个结点包括:姓名、电话号码、分类(可选项有:A 办公类 B 个人类 C 商务类)、电子邮件。
例如:杨春135****4454商务类*************(3)当录入了重复的姓名和电话号码时,则提示数据录入重复并取消录入;当通信录中超过15条信息时,存储空间已满,不能再录入新数据;录入的新数据能按递增的顺序自动进行条目编号。
(4)修改功能:选中某个人的姓名时,可对此人的相应数据进行修改(5)删除功能:选中某个人的姓名时,可对此人的相应数据进行删除,并自动调整后续条目的编号。
系统功能需求分析:主要包含以下几种功能:1.建立通讯录(建立功能)2.删除通讯人(删除功能)3.保存通讯录(保存功能)4.读取通讯录文件(读取功能)5.查找通讯人(查找功能)6.添加通讯人(添加功能)7.修改通讯人信息(修改功能)8.退出通讯录系统二.概要设计系统功能模块图:建立功能:在主菜单中输入1,进入建立功能。
用户自己输入通讯录文件名,建立一个新的通讯录,便开始输入信息,一旦想结束添加,在输入姓名处输入“*”结束录入。
(当录入相同的姓名和电话时,系统会告诉你已经重复录入)删除功能:在主菜单中输入2,进入删除功能。
用户输入待删除人的姓名,系统会自动显示待删除人的信息,并且提示是否删除该通讯人。
(当输入的姓名不存在的时候,系统会告诉你此人不存在)保存功能:在主菜单中输入3,进入保存功能。
将你已经写好的通讯录保存在建立时创建的文件里面。
(当保存成功后,系统会告诉你保存成功)读取功能:在主菜单中输入4,进入读取功能。
读取一个任意一个已经存在的文件,用户可以输入想要读取的文件,一旦文件读取成功,系统会告诉你文件读取成功。
查找功能:在主菜单中输入5,进入查找功能。
查找方式有三种:1. 按姓名查找 2. 按类型查找 3. 查看所有人添加功能:在主菜单中输入6,进入添加功能。
在还没有读取或者建立一个新的通讯录的时候,添加功能是无效的,系统会告诉你请你先新建立一个通讯录或者先读取通讯录文件。
进入添加功能以后,可以按提示添加通讯人信息。
修改功能:在主菜单中输入7,进入修改功能。
在还没有读取或者建立一个新的通讯录的时候,修改功能也是无效的,系统会告诉你请你先新建立一个通讯录或者先读取通讯录文件。
修改功能是和删除功能一样,也是通过姓名进行查找的。
退出功能:在主菜单中输入8,退出通讯录管理系统。
三.详细设计(1)通讯录#define ID struct tel //宏定义,方便以后的使用struct tel{char name[10]; //姓名char tele[15]; //电话char style[15]; //类型char mail[20]; //邮箱ID * next;};void main(){ID *head=NULL; //这是这个程序的头,什么功能都是靠这个来进行链接的int choice; //存放用户的选择int j=0; //这个j是用于功能之间的配合使用while(1){system("cls"); //清屏printf("\n\n");printf("\t # # # # # System Of Communication # # # # #\n");printf("\t 1. 建立通讯录\n");printf("\t 2. 删除通讯人\n");printf("\t 3. 保存通讯录\n");printf("\t 4. 读取通讯录文件\n");printf("\t 5. 查找通讯人\n");printf("\t 6. 添加通讯人\n");printf("\t 7. 修改通讯人信息\n");printf("\t 8. 退出通讯录系统\n");printf("\t\t\t\t\tMade by 元达鹏\n");printf("\t # # # # # # # # # # # # # # # # # # # # # #\n");printf("\n\n");scanf("%d",&choice); //输入功能getchar(); //吸收回车键switch(choice){case 1:head=Create(); //创建j=1; //让功能7可以进得去break;case 2:head=Delete(head); //删除break;case 3:Save(head); //保存函数break;case 4:head=Read(); //读取文件的函数j=2; //让功能7可以进得去break;case 5:Search(head); //查找break;case 6:if((j==1)||(j==2)) //当你进入过创建或者读取之后才可以进入添加{head=Add(head); //添加}else{printf("在你添加通讯人的时候请先创建通讯录或者读取通讯录文件\n\n");printf("请按任意键返回主菜单\n");getch(); //按下任意键就进入下一条语句的函数}break;case 7:if((j==1)||(j==2)) //当你进入过创建或者读取之后才可以进入添加{head=Change(head); //修改}else{printf("在你删除通讯人的时候请先创建通讯录或者读取通讯录文件\n\n");printf("请按任意键返回主菜单\n");getch(); //按下任意键就进入下一条语句的函数}break;case 8:exit(0); //退出break;default:printf("你输入错了吧,请你重新输入\n");}}}(2)工作流程图①建立:建立一个通讯录④读取:读取文件中的通讯录⑥添加:添加通讯人⑦修改:通过名字修改通讯人信息四.程序源代码#include <stdio.h>#include <stdlib.h> //除了一些常用函数需要以外,如在网上查到的system清屏函数,exit退出函数也需要这个H文件#include <string.h> //程序中的字符比较strump函数需要这个H文件#include <conio.h> //在网上查的getch函数需要这一个H文件#define ID struct tel //宏定义,方便以后的使用struct tel{char name[10]; //姓名char tele[15]; //电话char style[15]; //类型char mail[20]; //邮箱ID * next;};int total=0; //通讯录人数的统计void Save(ID *head); //保存函数的声明,因为你在调用Create函数时用到了/************************************************函数名:Create(创建)*功能:创建一个单链表,把数据放在链表里面,一旦需要保存,就调用save函数保存在文件中*返回值:ID *(结构体指针)***********************************************/ID* Create(){total=0;int k=0;int i=0;ID *head,*p1,*p2,*p3; //创建一个头指针和两个可用于移动的指针char saveflag; //这个字符用来接收是否保存的Y or y的head=p1=p2=NULL; //首先把上述的指针赋值为空while(1) //这个循环可以实现多次添加通讯人{p1= (ID*)malloc(sizeof(ID)); //给p1分配一个动态存储空间printf("请输入姓名,当你不想录入时,在姓名处输入*,结束录入\n");scanf("%s",p1->name); //输入姓名if(strcmp(p1->name,"*")==0) //这里是结束函数的一个通道(没有输入联系人),就是判断输入的是否为*号{if(total==0) //当记录人数为0时做以下事情{printf("你输入了0条记录,单链表没有创建...\n");free(p1); //释放p1空间return (head); //把head返回}else{break; //跳出while循环}}printf("请输入电话号码:\n");scanf("%s",p1->tele);printf("请输入类别:办公类、个人类、商务类\n");scanf("%s",p1->style);printf("请输入邮箱:\n");scanf("%s",p1->mail);if(k>0){p3=head; //让p3从头开始遍历while(p3!=NULL) //当p3不为空时{if((strcmp(p1->name,p3->name)==0)&&(strcmp(p1->tele,p3->tele)==0)){free(p1);printf("你重复输入了,这一条不保存。
请按任意键返回主菜单\n");i=1;printf("请按任意键返回主菜单\n");getch(); //按下任意键就进入下一条语句的函数break;}if((strcmp(p1->name,p3->name))&&(strcmp(p1->tele,p3->tele))&&(p3==p2)) //一旦到了最后一个结点,并且还没有和他相同的信息的时候{i=0;break; //跳出第一个循环}p3=p3->next;}if(i==1){break; //跳出第二个循环}}if(head==NULL) //这是第一次进来的时候,head为空{head=p1; //head和p2都为p1p2=p1;}else{p2->next=p1; //这是第二次以后的执行命令,目的就是p2向后移,而head 的位置不变p2=p1;}total++; //这是录入一个人后,总数就加1k++;}p2->next=NULL; //把最后一个的指针域赋值为NULL,在以后的函数中,很多判断都是靠这一点来实现的,所以很重要if(i==0){free(p1);printf("\n新建通讯录成功,共有%d个联系人,是否保存?(Y/N)\n ",total);getchar(); //这个getchar是吸收回车键的,十分重要scanf("%c",&saveflag); //写入一个字符if(saveflag=='y'||saveflag=='Y') //判断它是不是为Y or ySave (head); //进入到保存函数里面,保存到文件里面elseprintf("\n没有保存到成功保存到文件,请在返回主菜单后输入3保存通讯录。