引言:当我们C语言语法大部分都学习完的情况下,可以尝试一些项目来提升自己,比如下面的这个通讯录。
玩法介绍:我们需要对通讯录里面的个人信息进行增删查改以及排序等操作
技能要求:学习完大部分的C语言语法知识。
接下来我将创建三个文件:具备
函数声明
、宏定义
、所需库函数
的头文件
以及还有两个函数实现的源文件
以及测试项目逻辑的源文件
。
文件名如下:
- Contact.c (通讯录函数实现的源文件)
- Contact.h(通讯录的头文件)
- test.c(项目逻辑测试的源文件)
项目大纲
在正式写项目之前,我们要在脑海里面有一个对项目的大体流程。
- 项目的基本逻辑
- 创建通讯录(能容纳100个个人信息的通讯录以及记载当前存储通讯录个数)
- 初始化通讯录信息
- 添加联系人
- 全部显示联系人
- 删除联系人
- 查找联系人
- 修改联系人
- 模拟快排并排序通讯录信息
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.Sort *****\n");
printf("******************************\n");
}
void test()
{
int input = 0;
Contact Con;
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 SORT:
Bubble_sort(&(Con.data[0]), MAX, sizeof(Con.data[0]), cmp_by_name);
break;
case EXIT:
break;
default:
printf("输入有误,请重新输入!!!\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
Contact.c(通讯录函数实现的源文件)
初始化通讯录
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc != NULL);
//不借助memset,实现手搓对通讯录进行初始化
int size = sizeof(pc->data);
char* ptr = pc->data;
int i = 0;
for (i = 0; i < size; i++)
{
ptr[i] = 0;
}
pc->sz = 0;
}
添加联系人
//清空缓冲区
void Clear_Buffer_area()
{
while (getchar() != '\n')
{
;
}
}
//添加联系人
void AddContact(Contact* pc)
{
assert(pc != NULL);
if (pc->sz == MAX)
{
printf("通讯录已满,无法添加联系人!!!\n");
return;
}
printf("请输入你的名字:");
scanf("%s", pc->data[pc->sz].name);
//字符串输入会在缓冲区留下'\n'
//所以我们在输入完字符串的时候做一个清空缓冲区的操作
Clear_Buffer_area();
printf("请输入你的年龄:");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入你的性别:");
scanf("%s", pc->data[pc->sz].sex);
Clear_Buffer_area();
printf("请输入你的电话:");
scanf("%s", pc->data[pc->sz].tele);
Clear_Buffer_area();
printf("请输入你的地址:");
scanf("%s", pc->data[pc->sz].addr);
Clear_Buffer_area();
pc->sz++;
printf("成功添加联系人!!!\n");
}
全部显示联系人
void title()
{
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
}
//显示全部联系人
void ShowContact(const Contact* pc)
{
assert(pc != NULL);
int i = 0;
title();
if (pc->sz == 0)
{
printf("-> 暂时未添加联系人!!!<-\n");
}
for (i = 0; i < pc->sz; i++)
{
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
删除联系人
//手搓字符串比对函数
int my_strcmp(char* str1, char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
int i = 0;
//匹配需要查找的联系人名字
for (i = 0; i < pc->sz; i++)
{
if (my_strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return -1;
}
//删除联系人
void DelContact(Contact* pc)
{
assert(pc != NULL);
if (pc->sz == 0)
{
printf("暂未有联系人,无需删除!!!\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入需要删除的联系人名字:");
scanf("%s", name);
int pos = Find_Name(pc, name);
//判断有没有找到联系人
if (pos == -1)
{
printf("没有找到该联系人!!!\n");
return;
}
//判断是不是最后一个联系人
if (pos == pc->sz - 1)
{
//直接进行对存储的个数 - 1操作,不需要覆盖。
pc->sz--;
printf("成功删除联系人!!!\n");
return;
}
//删除联系人
int i = 0;
for (i = pos; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
printf("成功删除联系人!!!\n");
//删除完了还需要进行对存储个数 - 1操作。
pc->sz--;
}
查找联系人
//手搓字符串比对函数
int my_strcmp(char* str1, char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
int i = 0;
//匹配需要查找的联系人名字
for (i = 0; i < pc->sz; i++)
{
if (my_strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return -1;
}
//标题
void title()
{
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
}
//查找联系人
void SearchContact(const Contact* pc)
{
assert(pc != NULL);
if (pc->sz == 0)
{
printf("还没有添加联系人!!!\n");
}
char name[MAX_NAME] = { 0 };
printf("请输入你要查找的联系人名字:");
scanf("%s", name);
int pos = Find_Name(pc, name);
if (pos == -1)
{
printf("暂未查找到该联系人!!!\n");
return;
}
else
{
title();
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
}
修改联系人信息
//手搓字符串比对函数
int my_strcmp(char* str1, char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
int i = 0;
//匹配需要查找的联系人名字
for (i = 0; i < pc->sz; i++)
{
if (my_strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return -1;
}
void menu_modify()
{
printf("*******************************\n");
printf("***** 1.name 2.age *****\n");
printf("***** 3.sex 4.tele *****\n");
printf("***** 5.addr 0.exit *****\n");
printf("*******************************\n");
}
//修改联系人信息
void ModifyContact(Contact* pc)
{
assert(pc != NULL);
if (pc->sz == 0)
{
printf("还没有添加联系人!!!\n");
}
char name[MAX_NAME] = { 0 };
printf("请输入你要修改的联系人名字:");
scanf("%s", name);
int pos = Find_Name(pc, name);
if (pos == -1)
{
printf("暂未查找到该联系人!!!\n");
return;
}
else
{
int input = 0;
do
{
menu_modify();
printf("请输入你需要修改的信息:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入你的名字:");
scanf("%s", pc->data[pos].name);
printf("修改成功!!!\n");
break;
case 2:
printf("请输入你的年龄:");
scanf("%d", &(pc->data[pos].age));
printf("修改成功!!!\n");
break;
case 3:
printf("请输入你的性别:");
scanf("%s", pc->data[pos].sex);
printf("修改成功!!!\n");
break;
case 4:
printf("请输入你的电话:");
scanf("%s", pc->data[pos].tele);
printf("修改成功!!!\n");
break;
case 5:
printf("请输入你的地址:");
scanf("%s", pc->data[pos].addr);
printf("修改成功!!!\n");
break;
case 0:
printf("退出选项!!!\n");
break;
default:
printf("输入有误,请重新输入!!!\n");
break;
}
} while (input);
}
}
模拟快排并排序通讯录信息
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//因为是字符串,所以我们通过my_strcmp进行比对大小
int cmp_by_name(void* pf1, void* pf2)
{
return my_strcmp(((People_Info*)pf1)->name, ((People_Info*)pf2)->name);
}
//两数交换
void Swap(char* buf1, char* buf2, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
char tmp = *(buf1 + i);
*(buf1 + i) = *(buf2 + i);
*(buf2 + i) = tmp;
}
}
void Bubble_sort(People_Info* stu, int num, int sz, int (*cmp_by_name)(void* pf1, void* pf2))
{
int i = 0;
for (i = 0; i < num; i++)
{
int j = 0;
for (j = 0; j < num - i - 1; j++)
{
//通过我们自己创造的函数进行比对结果
if (cmp_by_name((char*)stu + j * sz, (char*)stu + (j + 1) * sz) < 0)
{
Swap((char*)stu + j * sz, (char*)stu + (j + 1) * sz, sz);
}
}
}
}
输出结果:
Contact.h(通讯录头文件)
通讯录头文件
#pragma once
#include <stdio.h>
#include <assert.h>
#define MAX 20
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
enum OPTION
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
typedef struct People_Info People_Info;
struct People_Info
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
typedef struct Contact Contact;
struct Contact
{
People_Info data[MAX];
int sz;
};
//初始化通讯录
void InitContact(Contact* Con);
//添加联系人
void AddContact(Contact* Con);
//显示全部联系人
void ShowContact(const Contact* Con);
//删除指定联系人
void DelContact(Contact* Con);
//查找指定联系人
void SearchContact(const Contact* Con);
//修改指定联系人信息
void ModifyContact(Contact* Con);
//字符串比较函数
int my_strcmp(char* str1, char* str2);
//手搓快排
void Bubble_sort(People_Info* stu, int num, int sz, int (*cmp_by_name)(void* pf1, void* pf2));
//声明cmp_by_name
int cmp_by_name(void* pf1, void* pf2);
总结:
该项目主要功能就是对通讯录内的信息完成增删查改以及模拟快排并排序通讯录信息功能,当你学习完大部分内容的情况下,该项目还是非常适合巩固自己所学的知识。
如果该项目对你有帮助的话,不妨留下一个赞吧。
本章完~
标签:sz,name,int,联系人,C语言,pc,通讯录,printf From: https://blog.csdn.net/m0_74445256/article/details/143064142