- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
需求分析
程序架构
代码实现(分函数呈现)
(1)主函数代码实现
(2)菜单函数的实现
(3)初始化功能实现
(4)添加联系人功能实现
(5)删除通讯录中的信息
(6)查找通讯录中联系人的信息
(7)查找函数实现
(8)修改联系人的信息
(9)打印通讯录中联系人的信息
(10)对通讯录中联系人的信息进行排序
(11)清空通讯录中联系人的信息
(1)test.c
(2)contact.h
(3)contact.c
通过C语言实现简单的通讯录管理系统,要求实现的功能有:增加联系人信息、删除联系人信息、查找联系人信息、修改联系人信息、清空联系人信息、对联系人的信息进行排序、显示联系人信息。
程序分为test.c、contact.c两个源文件和contact.h一个头文件。
test.c:主函数接口引入。
contact.c:函数主要实现
contact.h:头文件引入、函数声明、结构体声明。
int main()
{
//创建通讯录
struct contact con;//con就是通讯录,里面包含1000个元素的数组和size
//初始化通讯录
Init_Contact(&con);
int input = 0;
int size = 0;//记录当前有多少人
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case ADD:
//增加
Add_Contacter(&con);
break;
case DEL:
//删除
Del_Contacter(&con);
break;
case SEARCH:
//查找
Find_Contacter(&con);
break;
case MODIFY:
//修改
Mod_Contacter(&con);
break;
case SHOW:
//打印
Print_Contacter(&con);
break;
case CLEAR:
//清空
Clear_Contacter(&con);
break;
case SORT:
//排序
Sort_Contacter(&con);
break;
case EXIT:
//退出
printf("退出通讯录!\n");
break;
default:
printf("选择错误,请重新输入!\n");
}
} while (input);
return 0;
}
分析:主要是引入函数的接口,此处用了常见的do while循环,并且将input变量作为while()后面括号中的条件,此处是一个极其巧妙的运用,当input变量为0时循环结束,程序终止,此时也与前面的switch和case进行了一一对应。
void menu()
{
printf("************************************\n");
printf("**** 1.add 2.del ****\n");
printf("**** 3.search 4.modify ****\n");
printf("**** 5.show 6.clear ****\n");
printf("**** 7.sort 0.exit ****\n");
printf("************************************\n");
}
分析:简单运用printf将菜单进行输出,通过*来使输出形式更加清晰简洁美观。
//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;//设置通讯录最初只有0个元素
}
分析:通过memset()内存函数初始化通讯录中的信息,同时将size记录联系人数目的变量设置为0。
//添加通讯录中的信息
void Add_Contacter(struct contact* ps)
{
if (ps->size == MAX_NUM)
{
printf("通讯录已满!无法继续增加!\n");
}
else
{
printf("请输入名字:");
scanf("%s", &ps->data[ps->size].name);
printf("请输入年龄:");
scanf("%d", &ps->data[ps->size].age);
printf("请输入性别:");
scanf("%s", &ps->data[ps->size].sex);
printf("请输入电话:");
scanf("%s", &ps->data[ps->size].phone);
printf("请输入地址:");
scanf("%s", &ps->data[ps->size].address);
ps->size++;
printf("添加成功!\n");
}
}
分析:在进行添加时要注意进行分情况讨论,首先就是当联系人数目满了的时候就无法继续添加,只有当联系人数目未满的时候才能继续添加,添加后,要将记录联系人数目的变量size进行加一。
//删除通讯录中的信息
void Del_Contacter(struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要删除的联系人的姓名:");
scanf("%s", name);
//查找要删除的人所在的位置
//找到了返回名字所在元素的下标,没找到就返回-1
int pos = Find_byName(ps,name);
if (pos==-1)//删除的人不存在
{
printf("要删除的人不存在!\n");
}
else//删除
{
int j = 0;
for (j = pos; j < ps->size-1; j++)
{
ps->data[j] = ps->data[j + 1];
}
ps->size--;
printf("删除成功!\n");
}
}
分析:删除操作并不复杂,就是先查找到我们想要删除的那个联系人,然后将这个联系人后面的信息逐个向前进行覆盖,同时将记录联系人数目的变量size的值进行减1。
//查找通讯录中的信息
void Find_Contacter(const struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要查找的联系人的姓名:");
scanf("%s", name);
int pos = Find_byName(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].phone,
ps->data[pos].address);
}
}
分析:首先先通过查找函数将我们想要查找到的联系人找到,然后通过printf函数打印联系人的信息。
static int Find_byName(const struct contact* ps, char name[MAX_NAME])
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->data[i].name, name))
{
return i;
}
}
return -1;
}
分析:此处查找函数是通过遍历联系人中的信息进行实现的,当我们想查找的联系人的信息与某个联系人的信息一致时就停止下来,如果能够找到就返回其对应的下标,如果找不到就返回-1。
//修改通讯录中的信息
void Mod_Contacter(struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要修改的联系人的姓名:");
scanf("%s", name);
int pos = Find_byName(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].phone);
printf("请输入地址:");
scanf("%s", &ps->data[pos].address);
printf("修改成功!\n");
}
}
分析:修改联系人的信息与上面其实类似,首先是找到我们想要修改的联系人的信息,然后再进行修改。
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps)
{
if (ps->size == 0)
{
printf("通讯录为空!\n");
}
else
{
//标题
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
int i = 0;
while (i < ps->size)
{
//数据
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].phone,
ps->data[i].address);
i++;
}
}
}
分析:这个功能并不难实现,就是设置一个循环变量i,然后从头开始对通讯录信息进行遍历,当i小于size的时候将对应联系人的信息打印出来。
//对通讯录中的信息进行排序
//排序函数
//1.按照姓名进行排序
int Conpare_ByName(const void *e1,const void *e2)
{
return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
return ((struct PeoInfo*)e1)->age-((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
return strcmp(((struct PeoInfo*)e1)->address, ((struct PeoInfo*)e2)->address);
}
void Sort_Contacter(struct contact* ps)
{
printf("请选择你想排序的方式:\n");
printf("1.姓名\n2.年龄\n3.住址\n");
int input = 0;
scanf("%d", &input);
switch (input)
{
case 1:
qsort(ps->data,ps->size,sizeof(ps->data[0]),Conpare_ByName);
printf("排序成功\n");
break;
case 2:
qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAge);
printf("排序成功\n");
break;
case 3:
qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAddress);
printf("排序成功\n");
break;
}
}
分析:此处运用了qsort快速排序的函数,此处的关键就是设定好自己想要排序的依据,比如我们想根据年龄或者名字进行排序,此处要求掌握快速排序函数的使用。
//清空通讯中的信息
void Clear_Contacter(struct contact* ps)
{
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;
printf("清空成功!\n");
}
分析:此处其实类似于初始化联系人的信息,就是将那段内存空间中的数据使用memset函数全部设置为0,然后将记录联系人数目的变量size设定为0。
#include"contact.h"
enum Option
{
EXIT,//0
ADD,//1
DEL,//2
SEARCH,//3
MODIFY,//4
SHOW,//5
CLEAR,//6
SORT//7
};
void menu()
{
printf("************************************\n");
printf("**** 1.add 2.del ****\n");
printf("**** 3.search 4.modify ****\n");
printf("**** 5.show 6.clear ****\n");
printf("**** 7.sort 0.exit ****\n");
printf("************************************\n");
}
//测试函数的功能
int main()
{
//创建通讯录
struct contact con;//con就是通讯录,里面包含1000个元素的数组和size
//初始化通讯录
Init_Contact(&con);
int input = 0;
int size = 0;//记录当前有多少人
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case ADD:
//增加
Add_Contacter(&con);
break;
case DEL:
//删除
Del_Contacter(&con);
break;
case SEARCH:
//查找
Find_Contacter(&con);
break;
case MODIFY:
//修改
Mod_Contacter(&con);
break;
case SHOW:
//打印
Print_Contacter(&con);
break;
case CLEAR:
//清空
Clear_Contacter(&con);
break;
case SORT:
//排序
Sort_Contacter(&con);
break;
case EXIT:
//退出
printf("退出通讯录!\n");
break;
default:
printf("选择错误,请重新输入!\n");
}
} while (input);
return 0;
}
#pragma once
#define MAX_NUM 100
#define MAX_NAME 20
#define MAX_PHONE 12
#define MAX_SEX 5
#define MAX_ADDRESS 30
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct PeoInfo
{
char name[MAX_NAME];
char phone[MAX_PHONE];
char sex[MAX_SEX];
char address[MAX_ADDRESS];
int age;
};
struct contact
{
struct PeoInfo data[MAX_NUM];
int size;//记录当前已经有的元素个数
};
//声明函数
//初始化通讯录的函数
void Init_Contact(struct contact* ps);
//增加一个信息到通讯录
void Add_Contacter(struct contact* ps);
//删除指定的联系人
void Del_Contacter(struct contact* ps);
//查找指定人的信息
void Find_Contacter(const struct contact* ps);
//修改指定人的信息
void Mod_Contacter(struct contact* ps);
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps);
//对通讯录中的联系人进行排序
void Sort_Contacter(struct contact* ps);
//清空通讯录中的信息
void Clear_Contacter(struct contact* ps);
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
//实现函数的功能
static int Find_byName(const struct contact* ps, char name[MAX_NAME])
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->data[i].name, name))
{
return i;
}
}
return -1;
}
//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;//设置通讯录最初只有0个元素
}
//添加通讯录中的信息
void Add_Contacter(struct contact* ps)
{
if (ps->size == MAX_NUM)
{
printf("通讯录已满!无法继续增加!\n");
}
else
{
printf("请输入名字:");
scanf("%s", &ps->data[ps->size].name);
printf("请输入年龄:");
scanf("%d", &ps->data[ps->size].age);
printf("请输入性别:");
scanf("%s", &ps->data[ps->size].sex);
printf("请输入电话:");
scanf("%s", &ps->data[ps->size].phone);
printf("请输入地址:");
scanf("%s", &ps->data[ps->size].address);
ps->size++;
printf("添加成功!\n");
}
}
//删除通讯录中的信息
void Del_Contacter(struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要删除的联系人的姓名:");
scanf("%s", name);
//查找要删除的人所在的位置
//找到了返回名字所在元素的下标,没找到就返回-1
int pos = Find_byName(ps,name);
if (pos==-1)//删除的人不存在
{
printf("要删除的人不存在!\n");
}
else//删除
{
int j = 0;
for (j = pos; j < ps->size-1; j++)
{
ps->data[j] = ps->data[j + 1];
}
ps->size--;
printf("删除成功!\n");
}
}
//查找通讯录中的信息
void Find_Contacter(const struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要查找的联系人的姓名:");
scanf("%s", name);
int pos = Find_byName(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].phone,
ps->data[pos].address);
}
}
//修改通讯录中的信息
void Mod_Contacter(struct contact* ps)
{
char name[MAX_NAME];
printf("请输入你要修改的联系人的姓名:");
scanf("%s", name);
int pos = Find_byName(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].phone);
printf("请输入地址:");
scanf("%s", &ps->data[pos].address);
printf("修改成功!\n");
}
}
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps)
{
if (ps->size == 0)
{
printf("通讯录为空!\n");
}
else
{
//标题
printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
int i = 0;
while (i < ps->size)
{
//数据
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].phone,
ps->data[i].address);
i++;
}
}
}
//对通讯录中的信息进行排序
//排序函数
//1.按照姓名进行排序
int Conpare_ByName(const void *e1,const void *e2)
{
return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
return ((struct PeoInfo*)e1)->age-((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
return strcmp(((struct PeoInfo*)e1)->address, ((struct PeoInfo*)e2)->address);
}
void Sort_Contacter(struct contact* ps)
{
printf("请选择你想排序的方式:\n");
printf("1.姓名\n2.年龄\n3.住址\n");
int input = 0;
scanf("%d", &input);
switch (input)
{
case 1:
qsort(ps->data,ps->size,sizeof(ps->data[0]),Conpare_ByName);
printf("排序成功\n");
break;
case 2:
qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAge);
printf("排序成功\n");
break;
case 3:
qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAddress);
printf("排序成功\n");
break;
}
}
//清空通讯中的信息
void Clear_Contacter(struct contact* ps)
{
memset(ps->data, 0, sizeof(ps->data));
ps->size = 0;
printf("清空成功!\n");
}
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!