当前位置:天才代写 > C++/C代写 > 通讯录+课程报告 C++源码最新

通讯录+课程报告 C++源码最新

2017-09-07 08:00 星期四 所属: C++/C代写 浏览:65

 

 
#include 
#include 
#include 
 

//链表操作有关的宏
#define  TRUE         1
#define  FALSE        0
#define  OK           1
#define  ERROR        0
#define  INFEASIBLE  -1
#define  OVERFLOW    -2
typedef  int  STATUS;
//定义数据对象的类型
typedef  struct student
{
char  ID[16];        //成员ID号
char  name[16];      //成员姓名
char  sex[3];         //成员性别
int   score[2];      //成员的年龄和电话
char  add[16];       //成员地址
char  email[16];   //成员e-mail地址
char   job[16];  //职业
}ElemType, STUDENT;

//定义链表结点结构
typedef  struct lnode
{
ElemType  data;        //结点数据
struct lnode  *next;   //指向下一个结点的指针
}LNode, *LinkList, *ListType;
 
//链表操作函数声明
STATUS InitList(LinkList &L );
STATUS DestroyList(LinkList &L );
STATUS ClearList(LinkList L );
STATUS ListEmpty(LinkList L );
STATUS ListLength(LinkList L );
STATUS GetElem(LinkList L, int i, ElemType &e );
int    LocateElem(LinkList L, ElemType e,
STATUS (*compare)(ElemType e1, ElemType e2) );
STATUS ListInsert(LinkList L, int i, ElemType e );
STATUS ListDelete(LinkList L, int i, ElemType &e );
STATUS ListTraverse(LinkList L, STATUS (*visit)(ElemType e) );
STATUS ListModify(LinkList L, int i, ElemType e );
//文件操作
void LoadData(LinkList  L, char *filename );
void SaveData(LinkList  L, char *filename );
 
 

//该函数根据用户的选择,完成指定的操作
void UserOperate(ListType  L);

/* 用户操作界面启动时,在显示器上显示一些欢迎信息 */
void PrintWelcome( );

/* 在显示器上显示用户可以进行的操作,以及操作的方法 */
void PrintOption( );
/* 程序退出时,在显示器上显示一些感谢语言,以给使用者一个好印象 */
void PrintBuy( );

//往线性表中添加一个成员
void AddStu(ListType  L);
//从线性表中删除一个成员,根据成员ID决定删除哪个学生
void DelStu(ListType  L);
//修改成员信息,根据ID决定修改哪个
void ModifyStu(ListType  L);
//根据ID查询
void chkStu(ListType  L);
//根据姓名查询信息
void checkname(ListType L);
//根据姓名排序
void Arrangename(ListType L);
//打印
void Prntname(ListType L);
//根据ID排序
void ArrangeID(ListType L);
//打印
void PrntID(ListType L);
//根据职业排序
void ArrangeJob(ListType L);
//打印
void PrntJob(ListType L);
//打印一个人的信息
//调用ListTraverse()函数的时候,将该函数的名字作为第二个参数传递给visit
STATUS  PrntOneStu(ElemType  stu );
//打印所有人信息
void PrntAll(ListType  L);
 
void main()
{
ListType  L;
//初始化链表
InitList(L );

//从文件中读出数据并插入链表中
LoadData(L, "stuscore.dat" );

//调用用户界面,接受用户的操作选择
UserOperate(L);

//将链表中的数据保存到磁盘文件中
SaveData(L, "stuscore.dat" );

//销毁链表
DestroyList(L );
}
 
 
 
//该函数根据用户的选择,完成指定的操作
void UserOperate(ListType  L)
{
int  option = 0;
PrintWelcome( );    //显示欢迎信息
do
{
//提示用户操作选择
PrintOption( );
scanf("%d", &option );
//根据用户选择调用相关函数完成指定的操作
switch(option )
{
//添加一个成员
case 1:
AddStu(L);
break;

//删除成员
case 2:
DelStu(L);
break;
//修改各项信息
case 3:
ModifyStu(L);
break;
//根据ID查询各项信息
case 4:
chkStu(L);
break;
//根据姓名查询信息
case 5:
checkname(L);
break;
//打印所有成员信息
case 6:
PrntAll(L);
break;
//按姓名排序:
case 7:
Arrangename(L);
Prntname(L);
break;
//ID排序
case 8:
ArrangeID(L);
PrntID(L);
break;
//职业排序
case 9:ArrangeJob(L);
PrntJob(L);
break;
default: break;
}
}while(option );

//程序退出时,显示BYEBYE
PrintBuy( );
}

/* 用户操作界面启动时,在显示器上显示一些欢迎信息 */
void PrintWelcome( )
{
puts(" ");
puts("********************************************************************" );
puts("                     欢迎使用通讯录管理系统!" );
puts("********************************************************************" );
}

/* 在显示器上显示用户可以进行的操作 */
void PrintOption( )
{
puts(" ");
puts("请选择操作:" );
puts("0:退出系统 " );
puts("1:添加成员               2:删除成员               3:修改成员信息" );
puts("4:根据ID查询成员信息     5:根据姓名查询成员信息      6:打印所有信息 " );
puts("7:  按姓名排序             8:按ID排序                 9:按职业排序");
puts(" ");
}
/* 程序退出时,在显示器上显示一些感谢语言 */
void PrintBuy( )
{
puts("********************************************************************" );
puts("                   谢谢使用通讯录管理系统,再见!" );
puts("********************************************************************" );
puts(" ");
}
//比较两个成员信息的ID是否相等
//若相等则返回TRUE,否则返回FALSE
//当调用线性表操作函数int LocateElem(ListType L, ElemType e, STATUS (*compare)(ElemType e1, ElemType e2)
//的时候,将该函数名作为第三个参数传递给compare
STATUS NameEqual(ElemType e1, ElemType e2 )
{
if( strcmp(e1.name, e2.name)==0 )
return TRUE;
return FALSE;
}
STATUS IsEqual(ElemType e1, ElemType e2 )
{
if( strcmp(e1.ID, e2.ID)==0 )
return TRUE;
return FALSE;
}
//往线性表中添加一个成员
void AddStu(ListType  L)
{
ElemType  stu;
printf("请输入ID号(不超过15位):" );
getchar();  //吃掉前面的回车键,否则后面的字符串输入时会出错
gets(stu.ID );
printf("请输入姓名(不超过15位):" );
gets(stu.name );
printf("请输入年龄:" );
scanf("%d", &stu.score[0] );
printf("请输入电话:" );
scanf("%d", &stu.score[1] );
getchar();
printf("请输入工作:" );
gets(stu.job);
printf("请输入性别:");
gets(stu.sex);
printf("请输入地址:");
gets(stu.add);
printf("请输入email:");
gets(stu.email);
//判断线性表中是否已经存在该ID的人,如果已经存在,则放弃插入操作
if( LocateElem(L, stu, IsEqual) )
{
puts("操作失败,该成员已经存在" );
return;
}
//将该成员放入线性表中
//为简单起见,我们把新添加的结点放到线性表的前面
if( ListInsert(L, 1, stu ) )
puts("操作成功" );
else
puts("操作失败" );
}

//从线性表中删除一个成员,根据ID决定删除哪个成员
void DelStu(ListType  L)
{
ElemType stu;
int pos;
printf("请输入ID(不超过15位):" );
getchar();  //吃掉前面的回车键,否则后面的字符串输入时会出错
gets(stu.ID );
pos = LocateElem(L, stu, IsEqual );  //如果存在该ID的人,则返回其在线性表中的位序,如果不存在返回0
if(pos )
{
if(ListDelete(L, pos, stu) )
{
puts("操作成功");
return;
}
}
puts("操作失败" );
}

//修改成员信息,根据ID决定修改哪个
void ModifyStu(ListType  L)
{
int pos;
ElemType stu;
printf("请输入ID号(不超过15位):" );
getchar();  //吃掉前面的回车键,否则后面的字符串输入时会出错
gets(stu.ID );
printf("请输入姓名(不超过15位):" );
gets(stu.name );
printf("请输入年龄:" );
scanf("%d", &stu.score[0] );
printf("请输入电话:" );
scanf("%d", &stu.score[1] );
getchar();
printf("请输入工作:" );
gets(stu.job);
printf("请输入性别");
gets(stu.sex);
printf("请输入地址");
gets(stu.add);
printf("请输入email");
gets(stu.email);
pos = LocateElem(L, stu, IsEqual );
if(pos > 0 )
{
ListModify(L, pos, stu );
puts("操作成功" );
}
else
{
puts("操作失败" );
}

}
//根据ID查询某个人信息
void chkStu(ListType  L)
{
int pos;
ElemType stu;

printf("请输入ID号(不超过15位):" );
getchar();  //吃掉前面的回车键,否则后面的字符串输入时会出错
gets(stu.ID );

if(pos = LocateElem(L, stu, IsEqual) )
{
GetElem(L, pos, stu );
PrntOneStu(stu );
}
else
{
puts("操作失败" );
}
 
}
//根据姓名查询个人信息
void checkname(ListType  L)
{
int pos;
ElemType NAME;

printf("请输入姓名(不超过15位):" );
getchar();  //吃掉前面的回车键,否则后面的字符串输入时会出错
gets(NAME.name );

if(pos = LocateElem(L, NAME, NameEqual) )
{
GetElem(L, pos, NAME );
PrntOneStu(NAME );
}
else
{
puts("操作失败" );
}
 
}
//姓名排序
void Arrangename(ListType  L)
{
ListType p,q;
ElemType temp;
p=L->next;
while(p)
{
q=p->next;
while(q)
{
if(strcmp(p->data.name,q->data.name)>0)
{
temp=p->data;
p->data=q->data;
q->data=temp;
}
q=q->next;
}
p=p->next;
}

}
//打印姓名排序信息
void Prntname(ListType L)
{
Arrangename(L);
ListTraverse(L, PrntOneStu );
}
//ID排序
void ArrangeID(ListType  L)
{
ListType p,q;
ElemType temp;
p=L->next;
while(p)
{
q=p->next;
while(q)
{
if(strcmp(p->data.ID,q->data.ID)>0)
{
temp=p->data;
p->data=q->data;
q->data=temp;
}
q=q->next;
}
p=p->next;
}

}
//打印ID排序信息
void PrntID(ListType L)
{
ArrangeID(L);
ListTraverse(L, PrntOneStu );
}
//职业排序
void ArrangeJob(ListType  L)
{
ListType p,q;
ElemType temp;
p=L->next;
while(p)
{
q=p->next;
while(q)
{
if(strcmp(p->data.job,q->data.job)>0)
{
temp=p->data;
p->data=q->data;
q->data=temp;
}
q=q->next;
}
p=p->next;
}

}
//打印职业排序信息
void PrntJob(ListType L)
{
ArrangeJob(L);
ListTraverse(L, PrntOneStu );
}
//打印一个成员的信息
//调用ListTraverse()函数的时候,将该函数的名字作为第二个参数传递给visit
STATUS  PrntOneStu(ElemType  stu )
{
printf("%s    %s     %d     %d      %s     %s     %s     %s      \n", stu.ID, stu.name, stu.score[0], stu.score[1] ,stu.job,stu.sex,stu.add,stu.email);
return OK;
}
//打印所有成员信息
void PrntAll(ListType  L)
{
puts("ID :     姓名 :     年龄:     电话:    工作:    性别:       地址:     email地址:   ");
ListTraverse(L, PrntOneStu );
}
 
//初始化链表
STATUS InitList(LinkList &L )
{
//申请一个结点的内存作为头结点
L = (LinkList)malloc(sizeof(LNode) );
if(!L ) exit(OVERFLOW );
L->next = NULL;
return OK;
}

//销毁链表
//释放包括头结点的所有结点
STATUS DestroyList(LinkList &L )
{
LNode *p;
while(L )
{
p = L;
L = L->next;
free(p );
}
return OK;
}
//清空链表
//释放头结点之外的所有结点
STATUS ClearList(LinkList L )
{
LNode *p;
while(L->next )
{
p = L->next;
L->next = p->next;
free(p );
}
return OK;
}

//判断链表是否为空,
//返回值,空:TRUE;不空:FALSE
STATUS ListEmpty(LinkList L )
{
if(!L->next )
return TRUE;
return FALSE;
}
//求链表的长度,即链表中数据结点的个数
int ListLength(LinkList L )
{
int length;
LNode *p;
length = 0;
p = L->next;
while(p )
{
length++;
p=p->next;
}

return length;
}

//从链表中取位序为i的结点数据,并用e返回该值
STATUS GetElem(LinkList L, int i, ElemType &e )
{
int j=1;
LNode *p = L->next;
//找到元素所在的位置
while(p && j {
p = p->next;
j++;
}
if(!p || j>i )
return FALSE;     //找不到位序为i的结点
//找到位序为i的结点,用e把其数据返回
e = p->data;
return OK;
}
//判断元素e是否在链表中,如果在返回其在链表中的位序,否则返回0
int    LocateElem(LinkList L, ElemType e,
STATUS (*compare)(ElemType e1, ElemType e2) )
{
int pos = 1;
LNode  *p = L->next;
while(p )
{
if( (*compare)(e, p->data) )
return pos;               //元素e在链表中,返回其位置
pos++;
p = p->next;
}
return 0;    //元素e不在链表中,返回0
}

//往链表中添加一个结点,结点数据为e
STATUS ListInsert(LinkList L, int i, ElemType e )
{
LNode *p, *s;
int j;
//查找插入位置
j = 0;
p = L;
while(p && j {
p=p->next;
j++;
}
if(!p || j>i-1 )
return ERROR;
//申请结点存储空间,并放到链表中
s = (LNode*)malloc(sizeof(LNode) );
if(!s ) exit(OVERFLOW );
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
//删除位序为i的结点,并用e返回结点数据
STATUS ListDelete(LinkList L, int i, ElemType &e )
{
int j=1;
LNode *p = L;
LNode *q;
//找到元素所在的位置
while(p->next && j {
p = p->next;
j++;
}
if(!p->next || j>i )
return FALSE;     //找不到位序为i的结点
//找到结点,用e返回结点数据,并删除该结点
q = p->next;
p->next = q->next;
e = q->data;
free(q );
return OK;
}
//遍历链表中的每个结点,并调用visit()对结点数据处理
STATUS ListTraverse(LinkList L, STATUS (*visit)(ElemType e) )
{
LNode *p;
for(p=L->next; p; p=p->next )
{
if( !(*visit)(p->data) )
return ERROR;
}
return OK;
}
//修改位序为i的结点数据
STATUS ListModify(LinkList L, int i, ElemType e )
{
int j=1;
LNode *p = L->next;
//找到元素所在的位置
while(p && j {
p = p->next;
j++;
}
if(!p || j>i )
return FALSE;     //找不到位序为i的结点
//找到位序为i的结点,修改其结点数据
p->data = e;
return OK;
}
 

//从文件中将通讯录信息导入内存,每个信息用一个链表节点保存,从文件
//中顺序读通讯录信息的同时,将节点插入链表中
//文件内部数据存储格式如下
/************************************************************************************
| 存储第一个人的信 | 紧跟着存储第二个人      | 紧跟着存储第三个人   |
| 息,占的字节数为   | 的信息,占的字节数为  | 的信息,占的字节数为 |    …
| sizeof(STUDENT)个  | sizeof(STUDENT)个     | sizeof(STUDENT)个  |
|                    |                       |
|—-+—-+—-+—–|———————–|———————-|————–
|                    |        …            |        …           |     …
|—-+—-+—-+—–|———————–|———————-|————–
************************************************************************************/
void  LoadData(LinkList  L, char *filename )
{
STUDENT  student;      //大家注意STUDENT 数据类型,定义的时候是和ElemType等价的数据类型
FILE   *pfile;         //文件指针

//打开保存信息的数据文件
pfile = fopen(filename, "rb" );
if(pfile == NULL)
{
printf("文件打开失败!\n" );
exit(0 );
}
while(fread((char*)&student, sizeof(STUDENT), 1, pfile) == 1 )
ListInsert(L, 1, student );    //放到链表中
fclose(pfile );
pfile = NULL;
}
 
 
//将链表中的信息写到文件中,链表中每个节点都对应一个人的信息,
//文件内部数据存储格式如下
/************************************************************************************
| 存储第一个人的信 | 紧跟着存储第二个人  | 紧跟着存储第三个人 |
| 息,占的字节数为   | 的信息,占的字节数为  | 的信息,占的字节数为 |    …
| sizeof(STUDENT)个  | sizeof(STUDENT)个       | sizeof(STUDENT)个  |
|                    |                       |
|—-+—-+—-+—–|———————–|———————-|————–
|                    |        …            |        …           |     …
|—-+—-+—-+—–|———————–|———————-|————–
************************************************************************************/
void  SaveData(LinkList  L, char *filename )
{
long  lstunum=0;
LNode *pnode;
FILE  *pfile;

//打开保存信息的数据文件
pfile = fopen(filename, "wb" );
if(pfile == NULL )
{
printf("文件打开失败!\n" );
exit(0 );
}
//将链表中的信息存到文件中
pnode = L->next;
while(pnode != NULL )
{
fwrite(&(pnode->data), sizeof(STUDENT), 1, pfile );    //每次写入一个人(节点)信息
pnode = pnode->next;    //往后移动到下一个节点
lstunum += 1;           //统计人数
}

fclose(pfile );
pfile = NULL;
}

指定字符串的替换
电气 161 班  张三 学号:666666
程序分析和设计
参考手机中的电话薄管理模式,设计一个通讯录查询系统。通过该系统,可以方便查询通中成员的详细信息(ID号,姓名,性别,年龄,职业,电话,住址,E-mail等)。
1、基本要求
实现通讯录的增查改删、和排序。
2、扩展要求(自己加的)
1. 通讯录中所有成员按ID号排序;
2. 通讯录中所有成员按姓名排序;
3. 按职业分类显示所有成员信息;
自己设计一些合理的附加功能

 

功能分析和模块划分

从功能上说,该系统可以划分为两大功能模块,即数据(电话簿)管理模块和用户操作界面模块(人机交互模块)。

数据管理模块分析

1.该模块的功能是完成所有数据信息的管理,由于成员人数是动态变化的,所以程序中所有的数据采用链表的方式进行组织。程序运行的时候,把所有人的信息放到一个链表中管理。实际上,这个模块的功能是维护一个单向的链表。根据系统要求,应该实现的链表操作函数为:初始化链表、销毁链表,链表插入操作、链表删除操作、定位元素在链表中的位置、修改链表中某个结点的数据、获得链表中某个结点数据、遍历链表等。
2. 根据系统要求和采用的数据结构,设计相关的数据类型如下:
//定义数据对象的类型
typedef  struct student
{
char  ID[16];        //成员ID号
char  name[16];      //成员姓名
char  sex[3];         //成员性别
int   score[2];      //成员的年龄和电话
char  add[16];       //成员地址
char  email[16];   //成员e-mail地址
char   job[16];  //职业
}ElemType, STUDENT;
//定义链表结点结构
typedef  struct lnode
{
ElemType  data;        //结点数据
struct lnode  *next;   //指向下一个结点的指针
}LNode, *LinkList, *ListType;
3. 数据文件文件组织
文件名可设计为stuscore.dat,保存到可执行程序的当前目录下。
文件内部数据存储格式如下

存储第一个成员的信息,占字节数为sizeof(STUDENT)个 紧跟着存储第二个成员的信息占的字节数为sizeof(STUDENT)个
...

4. 主要函数设计
根据该模块的功能,设计本模块的主要函数如下:
/* 初始化链表 */
STATUS InitList(LinkList &L );

/* 销毁链表,释放包括头结点的所有结点 */
STATUS DestroyList(LinkList &L );

/* 从链表中取位序为i的结点数据,并用e返回该值 */
STATUS  GetElem(LinkList L, int i, ElemType &e );

/*判断元素e是否在链表中,如果在返回其在链表中的位序,否则返回0*/
int    LocateElem(LinkList L, ElemType e,
STATUS (*compare)(ElemType e1, ElemType e2) );

/*往链表中添加一个结点,结点数据为e*/
STATUS  ListInsert(LinkList L, int i, ElemType e );

/*删除位序为i的结点,并用e返回结点数据 */
STATUS  ListDelete(LinkList L, int i, ElemType &e );

/*遍历链表中的每个结点,并调用visit()对结点数据处理 */
STATUS  ListTraverse(LinkList L, STATUS (*visit)(ElemType e) );

/*修改位序为i的结点数据,将结点数据更新成e的值 */
STATUS  ListModify(LinkList L, int i, ElemType e );

/* 从文件中将成员信息导入内存,每个成员信息用一个链表节点保存,从文件中顺序读成员信息的同时,将节点插入链表中 */
void LoadData(LinkList L, char *filename );

/*将链表中的成员信息写到文件中,链表中每个节点都对应一个成员的信息
主函数设计 */
void SaveData(LinkList L, char *filename);

关键代码:

//往链表中添加一个成员
void AddStu();

//从链表中删除一个成员,根据成员的ID决定删除哪个成员
void DelStu();

//修改成员信息,根据ID决定修改哪个成员的信息
void ModifyStu();

//根据ID查询某个成员的信息
void chkStu();

//根据姓名查询个人信息
void checkname();

//姓名排序
void Arrangename()

//ID排序
void ArrangeID();

//职业排序
void ArrangeJob();

//打印所有成员信息
void PrntAll();

这个模块的对外接口函数为:
void  UserOperate( )
在这个函数中,根据用户的操作请求,调用对应的函数完成相应的操作。

运行效果



总结
我通过一个程序设计的练习,回顾了这一年里所学和数据结构的知识,也对这些有了更深的了解!同时通过这次实习我也了解都自己在知识掌握上的漏洞和一些实际操作上的不足之处。我也知道了自己今后需要努力的方向!这次实践让我受益非浅,我将在今后的学习中改掉不足之处,努力成为一个优秀的程序设计人员!
程序完全按照要求制作,在排序和查询上设置了更多的功能,希望能得到老师认可。

 

 

    关键字:


天才代写-代写联系方式