程序使用软件visual Studio 2022;
建立一个通讯录,可以对通讯录中的好友信息进行增加、删除、修改、查找以及对通讯录中的好友信息进行显示打印,提高对好友通讯录的管理效率。
知识目标:
(1)掌握模块化程序设计的方法;
(2)进一步掌握利用C语言进行程序设计的能力;
(3)进一步理解和运用结构化程序的设计的思想和方法
(4)学习和掌握C语言中的库函数及其应用。
能力培养目标:
(1)能正确分析现实生活中的问题,进行模块分析和编程;
(2)在程序调试过程中,能根据运行环境给出的错误提示,正确解决程序中的语法错误;
(3)在程序调试过程中,能根据运行结果,运用相应的手段,正确地找出并解决程序中的逻辑错误;
(4)在课程设计过程中,适当进行小组分工,培养团队谐调和团队合作的能力;
(5)提交课程设计成果报告,培养专业文档书写的能力。
Contact项目源文件说明:
Contact各个功能模块简要说明:
存放1000个好友的信息
名字、电话、性别、住址、年龄
1.增加好友信息
2.删除指定名字的好友信息
3.查找好友信息
4.修改好友信息
5.显示好友信息
6.对好友信息进行年龄排序
0.退出系统
题目需求分析
程序的用途:该项目程序主要面向需要记录好友联系方式进行管理通讯录的人群。
通过该程序用户可以非常方便快捷的对自己通讯录里的好友信息进行管理,可以对通讯录里的好友信息进行增加、删除、修改、查找等操作以及对通讯录中的好友信息进行显示打印。程序主要处理的数据为好友的名字、电话、性别、住址、年龄。每种数据按照程序设计类型进行输入。
总体设计
根据需求分析的结果,大题系统共设计六个功能模块:增加好友联系信息功能模块、删除好友联系信息功能模块、修改好友联系信息功能模块、查找好友联系信息功能模块、退出功能模块、显示好友联系信息模块。
系统模块图如下:
contact.h
//#define是一个预处理器指令,用于创建宏定义。它允许程序员为常量值、表达式、函数等创建符号名称,使代码更易于阅读、理解和维护.
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
#include
#include
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
QSORT
};
struct PeoInfor
{
char name[MAX_NAME];//名字
int age;//年龄
char sex[MAX_SEX];//性别
char tele[MAX_TELE];//电话
char addr[MAX_ADDR];//地址
};
struct Contact
{
struct PeoInfor data[MAX];//存放一个信息
int size;//记录当前已有的元素个数
};
//声明函数
//初始化通讯录
void InitContact(struct Contact* ps);
//添加一个好友信息到通讯录
void AddContact(struct Contact* ps);
//打印通讯录中的信息
//在结构体前使用 const 关键字可以创建一个只读(const-qualified)结构体。这表示结构体内的成员变量不能被修改。
void ShowContact(const struct Contact* ps);
//删除指定联系人
void DelContact(struct Contact* ps);
//查找指定的好友联系人信息
void SearchContact(const struct Contact* ps);
//修改联系人信息
void ModifyContact(struct Contact* ps);
//对好友联系人进行按年龄排序
void Qsort_Contact_age(struct Contact* ps);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//清空联系人结构体对象中的数据数组,并将联系人列表的元素个数初始化为 0。
// 这样做可以确保在创建联系人结构体对象时,它的数据成员得到适当的初始化,从而避免在使用时出现未初始化的值或者数据残留问题。
void InitContact(struct Contact* ps)
{
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;
};
//添加一个好友信息到通讯录
void AddContact(struct Contact* ps) {
int age;
FILE* file;
if (ps->size == MAX) {
printf("通讯录已满,无法增加");
}
else {
file = fopen("D:\contacts.txt", "a");
if (file == NULL) {
file = fopen("D:\contacts.txt", "w");
printf("无法打开文件");
return;
}
printf("请输入名字:>");
fscanf(stdin, "%s", ps->data[ps->size].name);
printf("请输入年龄:>");
fscanf(stdin, "%d", &(ps->data[ps->size].age));
printf("请输入性别:>");
fscanf(stdin, "%s", ps->data[ps->size].sex);
printf("请输入电话:>");
fscanf(stdin, "%s", ps->data[ps->size].tele);
printf("请输入地址:>");
fscanf(stdin, "%s", ps->data[ps->size].addr);
fprintf(file, "%s %d %s %s %s\n", ps->data[ps->size].name, ps->data[ps->size].age, ps->data[ps->size].sex, ps->data[ps->size].tele, ps->data[ps->size].addr);
ps->size++;
printf("成功添加好友信息");
fclose(file);
}
}
//显示打印好友通讯录中的信息
void ShowContact(const struct Contact* ps)
{
if (ps->size == 0)//判断通讯录中的好友数量信息是否为0
{
printf("该通讯录为空\n");
}
else
{
int i = 0;
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < ps->size; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr);
}
}
}
//按名字进行查找,找到返回相应下标,找不到返回-1;
static int FindByName(const struct Contact* ps, char name[MAX_NAME])
{
int i = 0;
for (i = 0; i < ps->size; i++) {
//strcmp 是一个字符串比较函数,用于比较两个字符串的大小关系 大于返回正数 小于返回负数 等于返回0
if (0 == strcmp(ps->data[i].name, name))
{
return i;
}
}
return -1;
}
//删除指定联系人
void DelContact(struct Contact* ps)
{
if (ps->size == 0)
{
printf("该通讯录为空,不能进行删除操作\n");
return 0;
}
char name[MAX_NAME];
printf("请输入要删除人的名字:>");
scanf("%s", name);
//1.查找要删除的人在什么位置
//找到了返回名字所在的下标,
//找不到返回-1
int pos = FindByName(ps, name);
//2.删除
if (pos == -1)
printf("要删除的人不存在!\n");
else
{
int j = 0;
for (j = pos; j < ps->size - 1; j++)
{
ps->data[j] = ps->data[j + 1];
}
int u=ps->size--;
FILE* file = fopen("D:\contacts.txt", "w");
if (file != NULL) {
for (int i = 0; i < u-1; i++) {
fprintf(file, "%s %d %s %s %s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr);
}
fclose(file);
}
else {
printf("无法打开文件");
}
printf("删除成功\n");
}
}
//查找指定的好友联系人信息
void SearchContact(const struct Contact* ps)
{
if (ps->size == 0)
{
printf("该表为空,无法进行搜索\n");
return 0;
}
char name[MAX_NAME];
printf("请输入要查找人的名字:>");
scanf("%s", name);
int pos = FindByName(ps, name);
if (pos == -1) {
printf("要查找的人不存在!\n");
}
else
{
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].addr);
}
}
//修改指定的好友联系人信息
void ModifyContact(struct Contact* ps)
{
if (ps->size == 0)
{
printf("该通讯录为空,不能进行修改操作\n");
return 0;
}
char name[MAX_NAME];
printf("请输入要修改人的名字:>");
scanf("%s", name);
int pos = FindByName(ps, name);
if (pos == -1)
{
printf("要修改人的信息不存在!\n");
}
else {
printf("请输入名字:>");
scanf("%s", ps->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(ps->data[pos].age));
printf("请输入性别:>");
scanf("%s", ps->data[pos].sex);
printf("请输入电话:>");
scanf("%s", ps->data[pos].tele);
printf("请输入地址:>");
scanf("%s", ps->data[pos].addr);
printf("修改成功\n");
}
int u = ps->size;
FILE* file = fopen("D:\contacts.txt", "w");
if (file != NULL) {
for (int i = 0; i < u ; i++) {
fprintf(file, "%s %d %s %s %s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr);
}
fclose(file);
}
else {
printf("无法打开文件");
}
}
//qsort 是C语言标准库 中的一个函数,用于对数组进行快速排序。它可以对数组中的元素按照指定的比较函数进行排序。
//void* 是 C 语言中的一种特殊类型,代表指向未知类型的指针。void* 类型的指针可以指向任何类型的数据,因为它是一个通用类型指针,不关心它指向的数据的具体类型。
// const void* 表示指向常量数据的 void* 类型指针。函数在使用这些指针时不能修改它们所指向的数据。
//利用Qsort函数实现对结构体数据按照年龄排序
static int cmp_stc_by_age(const void* e1, const void* e2)
{
return ((struct Contact*)e1)->data->age - ((struct Contact*)e2)->data->age;
}
void Qsort_Contact_age(struct Contact* ps)
{
if (ps->size == 0)//判断通讯录中的好友数量信息是否为0
{
printf("该通讯录为空,无法进行排序\n");
}
else {
//qsort四个参数含义:ps为待排序数组的起始地址 ps->size数组中元素的个数 sizeof(ps->data[0])为数组中每个元素的大小(以字节为单位)
//cmp_stc_by_age用于返回确认元素顺序的比较函数的指针
//比较函数cmp_stc_by_age应当接受两个 const void * 类型的参数,指向待比较的元素。该函数应当返回一个整数值来表示两个元素的大小关系:
//若返回值小于 0,表示第一个参数小于第二个参数;
//若返回值等于 0,表示两个参数相等;
//若返回值大于 0,表示第一个参数大于第二个参数。
qsort(ps, ps->size, sizeof(ps->data[0]), cmp_stc_by_age);
int i = 0;
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < ps->size; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr);
}
}
}
test.c
//#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu() {
printf("********************************************\n");
printf("*********1.add 2.del**********\n");
printf("*********3.search 4.modify************\n");
printf("*********5.show 6.qsort**************\n");
printf("********************0.exit********************\n");
printf("********************************************\n");
}
int main()
{
int input = 0;
int size = 0;
//创建通讯录
struct Contact con;//con就是通讯录,里面包含:1000的元素的通讯录信息和size;
InitContact(&con);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case QSORT:
Qsort_Contact_age(&con);
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}