一.实验目的
1、进一步掌握和利用C语言进行程设计的能力;
2、进一步理解和运用结构化程序设计的思想和方法;
3、初步掌握开发一个小型实用系统的基本方法;
4、学会调试一个较长程序的基本方法;
5、掌握书写程序设计开发文档的能力。
二、实验内容
(1)信息维护:联系人信息数据要以文件的形式保存,能实现联系人信息数据的维护。此模块包括子模块有:增加联系人信息、删除联系人信息、修改联系人信息。
(2)信息查询:要求:查询时可实现按姓名查询。
(3)信息全展示:要求显示全部联系人信息
(4)排序:按姓名排序
三、系统设计
包括系统功能框架、数据结构设计、函数说明、运行界面、测试数据等
1.运用while循环使用户可以持续操作,直至用户输入‘0’退出通讯录
2.menu函数声明
void menu() { printf("******************************************************n"); printf("**** 1.添加联系人 2. 删除联系人 ****n"); printf("**** 3.查找联系人 4. 修改联系人 ****n"); printf("**** 5.显示全部联系人 6. 按姓名排序联系人 ****n"); printf("**** 0.退出 ****n"); printf("******************************************************n"); }
3.运用switch对用户输入的数据进行分类并使用通讯录的不同功能
4.
链表的初始化:(1)采用带头的单链表存储数据
(2)SLinit函数声明
先打开文件data.txt
再从文件中读取数据存储至链表直至文件中的数据全部读取完毕
5.用户操作
(1)“添加联系人”
Slpushback函数声明
即尾插,将用户输入的联系人信息尾插入链表
(2)“删除联系人”
Sldelete函数声明
设置tail变量存储要删除的联系人所在节点的地址;
设置prevtail存储要删除的联系人的前一个结点的地址
prevtail->next = tail->next;
删除联系人节点
(3)“查找联系人”
Slfind函数声明
设置tail变量,遍历链表直至找到节点并打印该节点内容
(4)“修改联系人”
设置tail变量,遍历链表直至找到节点并改变除名字的其他信息
(5)“显示全部联系人”
设置tail变量,遍历链表的同时打印每一节点的内容。
(6)“按姓名排序联系人”
Slsort函数声明
//本质是冒泡排序
1.先设定min[10],运用strcpy函数将第一节点的姓名复制到min上,再遍历链表,运用strcmp函数比较min与当前节点,若结果<0,再将当前节点复制到min 再用flag存储当前节点的地址, 2.一轮循环结束后用slswap函数交换flag和这一轮循环的初节点 3.重新设置下一轮循环的初节点,flag,min,进行下一次循环,直至初节点的next为空
(7)退出
退出之后,再程序终止之前需要打开文件,写入这次更改添加的数据,最后关闭文件。
四、总结
主要问题出现在文件的读写和slsort函数的声明上,
(1)
在函数读入上学会了fscanf函数的使用并了解其返回值为读取成功的数据个数,若读取失败则返回-1,可用于while循环进行连续读取
(2)slsort函数
采用带头的单链表可以防止交换节点后找不到头节点,导致读取乱序。
需要考虑多种情况,若需要交换的节点为尾节点怎么办?,若循环一轮后不需要交换怎么办?交换后如何让链表重新链接起来?这些问题都通过不断调试才得以解决。
五.代码全览
1. contact.h
代码语言:javascript复制#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct SListnode
{
char name[10];
int age;
char number[20];
char place[10];
struct SListnode* next;
}SLnode;
void SLinit(SLnode* phead);//初始化
void add(SLnode* head);
void prSLpushback(SLnode* head, int x, char na[], char nu[], char p[]); //初始添加
void SLpushback(SLnode* head); //插入
SLnode* SLcreat(int x, char na[], char nu[], char p[]);
void SLdelete(SLnode* head); //删除
void SLfind(SLnode* head); //查找
void SLalter(SLnode* head); //修改
void SLprint(SLnode* head); //打印
void SLsort(SLnode* phead); //排序
void SLswap(SLnode* head, SLnode* flag); //交换
void SLsave(SLnode* head); //保存数据至文档
2.contact.c
代码语言:javascript复制#include"contact.h"
void prSLpushback(SLnode* head, int x, char na[], char nu[], char p[])
{
SLnode* newnode = SLcreat(x, na, nu, p);
SLnode* tail = head;
while (tail->next != NULL)
tail = tail->next;
tail->next = newnode;
}
void SLinit(SLnode* phead)
{
SLnode* tail = (SLnode*)malloc(sizeof(SLnode));
FILE* pf = fopen("data.txt", "r");
int flag=0;
if (pf == NULL)
{
perror("fopen");
return 1;
}
flag =fscanf(pf,"%s %d %s %s", tail->name, &tail->age, tail->number, tail->place);
while(flag>=0)
{
prSLpushback(phead,tail->age,tail->name,tail->number,tail->place);
flag = (fscanf(pf, "%s %d %s %s", tail->name, &tail->age, tail->number, tail->place));
}
fclose(pf);
pf = NULL;
}
void SLpushback(SLnode* head)
{
int age;
char name[10];
char number[20];
char place[10];
printf("请输入姓名:> ");
scanf("%s", name);
printf("请输入年龄:> ");
scanf("%d", &age);
printf("请输入电话号码:> ");
scanf("%s", number);
printf("请输入住址:> ");
scanf("%s", place);
SLnode* newnode = SLcreat(age,name,number,place);
SLnode* tail = head;
while (tail->next != NULL)
tail = tail->next;
tail->next = newnode;
}
SLnode* SLcreat(int x, char na[], char nu[], char p[])
{
SLnode* head = (SLnode*)malloc(sizeof(SLnode));
head->age = x;
strcpy(head->number, nu);
strcpy(head->name, na);
strcpy(head->place, p);
head->next = NULL;
return head;
}
void SLdelete(SLnode* head)
{
char n[10];
printf("输入要删除的联系人的姓名:> ");
scanf("%s", n);
SLnode* tail = head->next;
SLnode* prevtail = head;
while (strcmp(n, tail->name) != 0 && tail->next != NULL)
{
tail = tail->next;
}
if (strcmp(n, tail->name) != 0)
printf("输入错误");
else
{
while (prevtail->next != tail)
prevtail = prevtail->next;
if (tail->next == NULL)
prevtail->next = NULL;
else
{
prevtail->next = tail->next;
free(tail);
}
}
}
void SLfind(SLnode* head)
{
char n[10];
printf("输入要查找的联系人的姓名:> ");
scanf("%s", n);
SLnode* tail = head->next;
while (strcmp(n, tail->name) != 0 && tail->next != NULL)
{
tail = tail->next;
}
if (strcmp(n, tail->name) != 0)
printf("查无此人");
else
{
printf("姓名:%s ", tail->name);
printf("年龄:%d ", tail->age);
printf("电话号码:%s ", tail->number);
printf("住址:%s ", tail->place);
printf("n");
}
}
void SLalter(SLnode* head)
{
char n[10];
char a[10];
printf("输入要修改的联系人的姓名:> ");
scanf("%s", n);
SLnode* tail = head->next;
while (strcmp(n, tail->name) != 0 && tail->next != NULL)
{
tail = tail->next;
}
if (strcmp(n, tail->name) != 0)
printf("查无此人");
else
{
printf("输入修改后的联系人的姓名:> ");
scanf("%s", a);
strcpy(tail->name, a);
}
}
void SLprint(SLnode* head)
{
SLnode* tail = head->next;
while (tail!= NULL)
{
printf("姓名:%s ", tail->name);
printf("年龄:%d ", tail->age);
printf("电话号码:%s ", tail->number);
printf("住址:%s ", tail->place);
printf("n");
tail = tail->next;
}
}
void SLswap(SLnode* head, SLnode* flag)
{
SLnode* tail = head;
while (tail->next != flag)
tail = tail->next;
if (flag->next != NULL)
{
SLnode* ptail = flag->next;
flag->next = head->next;
tail->next = head;
head->next = ptail;
}
else
{
if (head->next == flag)
{
flag->next = head;
head->next = NULL;
}
else
{
flag->next = head->next;
tail->next = head;
head->next = NULL;
}
}
}
void SLsort(SLnode* phead)
{
SLnode* qhead = phead;
SLnode* head = phead->next;
SLnode* tail = phead->next;
SLnode* flag = NULL;
char min[10];
strcpy(min, phead->next->name);
while (head->next != NULL)
{
while (tail->next != NULL)
{
tail = tail->next;
if (strcmp(min, tail->name)>=0)
{
strcpy(min,tail->name);
flag = tail;
}
}
if (flag != NULL)
{
SLswap(head, flag);
qhead->next = flag;
qhead = qhead->next;
head = flag->next;
tail = head;
flag = NULL;
strcpy(min,head->name);
}
else
{
head = head->next;
tail = head;
qhead = qhead->next;
strcpy(min, head->name);
}
}
}
void SLsave(SLnode* head)
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
SLnode* tail = head->next;
while (tail != NULL)
{
fprintf(pf,"%s %d %s %sn",tail->name,tail->age,tail->number,tail->place);
tail = tail->next;
}
fclose(pf);
pf = NULL;
}
3.test.c
代码语言:javascript复制#include"contact.h"
void menu()
{
printf("******************************************************n");
printf("**** 1.添加联系人 2. 删除联系人 ****n");
printf("**** 3.查找联系人 4. 修改联系人 ****n");
printf("**** 5.显示全部联系人 6. 按姓名排序联系人 ****n");
printf("**** 0.退出 ****n");
printf("******************************************************n");
}
int main()
{
int flag = 1;
SLnode* sl = (SLnode*)malloc(sizeof(SLnode));
sl->age = 1;
strcpy(sl->number,"110");
strcpy(sl->name,"wang");
strcpy(sl->place,"beijing");
sl->next = NULL;
SLinit(sl);
while (flag)
{
menu();
printf("请选择> ");
scanf("%d", &flag);
switch (flag)
{
case 1: SLpushback(sl); //添加
break;
case 2: SLdelete(sl); //删除
break;
case 3: SLfind(sl); //查找
break;
case 4: SLalter(sl); //修改
break;
case 5: SLprint(sl); //打印
break;
case 6: SLsort(sl); //排序
break;
case 0: SLsave(sl);
//存储
break;
default:
break;
}
}
return 0;
}