电话号码查询系统的设计与实现(txt存储版本)

实验项目名称:

电话号码查询系统的设计与实现

实验目的与要求:

1.基础知识:

(1)掌握数据结构中的查找、排序等算法相关知识。

(2)掌握 C 或 C++语言中程序设计的方法。

2.程序功能:

(1)自选存储结构(顺序表或哈希表)实现电话号码表的初始化创建。

(2)编写一个电话号码查询系统,要求有电话号码记录的录入(插入)存储、查 询、删除、打印、排序(顺序表存储结构必须有排序功能,哈希表结构则可以无此功能) 等模块。

这里用的是哈希表的方式书写的,献丑了

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include<fcntl.h>#define Hash_Length 16
typedef struct {char* str;int length;
} String;typedef struct {String Name;String mobile_phone_number_one;String mobile_phone_number_two;String QQ_number;String dateTime;
} Contact;typedef struct {Contact contact;struct HashNode* next;
} HashNode;typedef struct HashTable {int length[Hash_Length];HashNode* table[Hash_Length];
} HashTable;//判断QQ号格式
bool isTrue_QQ_number(String str);
//判断手机号格式
bool isTrue_Mobile_phone_number(String str);
//判断格式是否正确
bool is_true(Contact contact);
//判断内容是否未空
bool isEmpty(char* str, int length);
//计算哈希值
int hashCode(String str);
//初始化
void CreateTable(HashTable* table);
//对比字符串的方法
bool equals(String str1, String str2);
//判断主要数据是否重复
bool is_Have(Contact contact, HashTable table);
//修改信息
void change_data(HashNode* node);
//输入信息
Contact* Scanf(Contact* contact);
Contact* Scanf_chance(Contact* contact);
//打印
void Print(Contact contact);
void ReadData(HashTable* table);
void InsertTable(HashTable* table, Contact contact);//判断QQ号格式
bool isTrue_QQ_number(String str) {if (str.length == 1) {return true;}if (str.length < 5 || str.length > 15) {printf("QQ号格式错误!\n");return false;}for (int i = 0; i < str.length; i++) {if (str.str[i] < '0' || str.str[i] > '9') {printf("QQ号格式错误!\n");return false;}}return true;
}//判断手机号格式
bool isTrue_Mobile_phone_number(String str) {if (str.length != 11 && str.length != 1) {printf("手机号格式错误!\n");return false;}for (int i = 0; i < str.length; i++) {if (str.str[i] < '0' || str.str[i] > '9') {printf("手机号格式错误!\n");return false;}}return true;
}//判断格式是否正确
bool is_true(Contact contact) {if (!isTrue_Mobile_phone_number(contact.mobile_phone_number_one) || !isTrue_Mobile_phone_number(contact.mobile_phone_number_two)) {return false;}if (!isTrue_QQ_number(contact.QQ_number)) {return false;}return true;
}//判断内容是否未空
bool isEmpty(char* str, int length) {if (length == 1 && str[0] == '0') {return true;}return false;
}//计算哈希值
int hashCode(String str) {int sum = 0;for (int i = str.length - 1; i > str.length - 5; i--) {sum += str.str[i];}return sum & (Hash_Length - 1);
}//初始化
void CreateTable(HashTable* table) {for (int i = 0; i < Hash_Length; i++) {table->table[i] = NULL;table->length[i] = 0;}ReadData(table);
}//对比字符串的方法
bool equals(String str1, String str2) {int num_str1 = 0;int num_str2 = 0;if (str1.length != str2.length) {return false;}if (str1.length >= 4) {for (int i = str1.length - 1; i > str1.length - 5; i--) {num_str1 += str1.str[i];num_str2 += str2.str[i];if (num_str1 != num_str2) {return false;}}}for (int i = 0; i < str1.length; i++) {if (str1.str[i] != str2.str[i]) {return false;}}return true;
}//判断主要数据是否重复
bool is_Have(Contact contact, HashTable table) {int index = hashCode(contact.mobile_phone_number_one);HashNode* temp = table.table[index];for (int i = 0; i < table.length[index]; i++) {if (equals(temp->contact.mobile_phone_number_one, contact.mobile_phone_number_one)) {return true;}temp = temp->next;}return false;
}//修改信息
void change_data(HashNode* node) {Contact* new_con = (Contact*)malloc(sizeof(Contact));new_con->mobile_phone_number_one.str = node->contact.mobile_phone_number_one.str;new_con->mobile_phone_number_one.length = strlen(new_con->mobile_phone_number_one.str);new_con = Scanf_chance(new_con);if (!is_true(*new_con)) {printf("输入记录有误!\n");return;}node->contact = *new_con;
}//输入信息
Contact* Scanf(Contact* contact) {contact->Name.str = (char*)malloc(50 * sizeof(char));printf("输入姓名:");scanf("%s", contact->Name.str);getchar();contact->Name.length = strlen(contact->Name.str);contact->mobile_phone_number_one.str = (char*)malloc(50 * sizeof(char));printf("输入号码1:");scanf("%s", contact->mobile_phone_number_one.str);getchar();contact->mobile_phone_number_one.length = strlen(contact->mobile_phone_number_one.str);contact->mobile_phone_number_two.str = (char*)malloc(50 * sizeof(char));printf("输入号码2:");scanf("%s", contact->mobile_phone_number_two.str);getchar();contact->mobile_phone_number_two.length = strlen(contact->mobile_phone_number_two.str);contact->QQ_number.str = (char*)malloc(50 * sizeof(char));printf("输入QQ号:");scanf("%s", contact->QQ_number.str);getchar();contact->QQ_number.length = strlen(contact->QQ_number.str);time_t rawtime;struct tm* timeinfo;time(&rawtime);timeinfo = localtime(&rawtime);contact->dateTime.str = _strdup(asctime(timeinfo));return contact;
}Contact* Scanf_chance(Contact* contact) {contact->Name.str = (char*)malloc(50 * sizeof(char));printf("输入姓名:");scanf("%s", contact->Name.str);getchar();contact->Name.length = strlen(contact->Name.str);contact->mobile_phone_number_two.str = (char*)malloc(50 * sizeof(char));printf("输入号码2:");scanf("%s", contact->mobile_phone_number_two.str);getchar();contact->mobile_phone_number_two.length = strlen(contact->mobile_phone_number_two.str);contact->QQ_number.str = (char*)malloc(50 * sizeof(char));printf("输入QQ号:");scanf("%s", contact->QQ_number.str);getchar();contact->QQ_number.length = strlen(contact->QQ_number.str);time_t rawtime;struct tm* timeinfo;time(&rawtime);timeinfo = localtime(&rawtime);contact->dateTime.str = _strdup(asctime(timeinfo));return contact;
}//打印
void Print(Contact contact) {printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");printf("姓名:%10s\n", contact.Name.str);printf("电话一:%s\n", contact.mobile_phone_number_one.str);printf("电话二:");if (contact.mobile_phone_number_two.length == 1) {printf("未填写\n");}else {printf("%s\n", contact.mobile_phone_number_two.str);}printf("QQ号:");if (contact.QQ_number.length == 1) {printf("未填写\n");}else {printf("%s\n", contact.QQ_number.str);}printf("记录时间:%s\n", contact.dateTime.str);
}
//txt保存
//存入txt
void Input(Contact contact) {FILE* file_out = fopen("output.txt", "a");if (file_out == NULL) {printf("无法打开文件,尝试创建新文件\n");file_out = fopen("output.txt", "w+");if (file_out == NULL) {printf("无法创建新文件\n");return 1;}}fprintf(file_out, contact.Name.str);fprintf(file_out, "|"); fprintf(file_out, contact.mobile_phone_number_one.str);fprintf(file_out, "|");fprintf(file_out, contact.mobile_phone_number_two.str);fprintf(file_out, "|");fprintf(file_out, contact.QQ_number.str);fprintf(file_out, "|");fprintf(file_out, contact.dateTime.str);fclose(file_out);
}
void writeData(HashTable table) {FILE* file_out = fopen("output.txt", "w");if (file_out == NULL) {printf("无法打开文件,尝试创建新文件\n");file_out = fopen("output.txt", "w+");if (file_out == NULL) {printf("无法创建新文件\n");return 1;}}fclose(file_out);for (int i = 0; i < Hash_Length; i++) {if (table.length[i] == 0) {continue;}HashNode* temp = table.table[i];for (int j = 0; j < table.length[i]; j++) {Input(temp->contact);temp = temp->next;}}
}
void ReadData(HashTable* table) {FILE* file_in = fopen("output.txt", "r");if (file_in == NULL) {printf("无法打开文件\n");return 1;}char line[100];const char delimiter[2] = "|";while (fgets(line, sizeof(line), file_in) != NULL) {char* token;int index = 0;Contact* con = (Contact*)malloc(sizeof(Contact));// 获取第一个子字符串token = strtok(line, delimiter);// 通过循环获取其他子字符串while (token != NULL) {switch (index){case 0:con->Name.str = (char*)malloc(strlen(token) + 1);strcpy(con->Name.str, token);con->Name.length = strlen(con->Name.str);break;case 1:con->mobile_phone_number_one.str = (char*)malloc(strlen(token) + 1);strcpy(con->mobile_phone_number_one.str, token);con->mobile_phone_number_one.length = strlen(con->mobile_phone_number_one.str);break;case 2:con->mobile_phone_number_two.str = (char*)malloc(strlen(token) + 1);strcpy(con->mobile_phone_number_two.str, token);con->mobile_phone_number_two.length = strlen(con->mobile_phone_number_two.str);break;case 3:con->QQ_number.str = (char*)malloc(strlen(token) + 1);strcpy(con->QQ_number.str, token);con->QQ_number.length = strlen(con->QQ_number.str);break;case 4:con->dateTime.str = (char*)malloc(strlen(token) + 1);strcpy(con->dateTime.str, token);con->dateTime.length = strlen(con->dateTime.str);break;}token = strtok(NULL, delimiter);index++;}InsertTable(table,*con);}fclose(file_in);
}//1.插入数据
void InsertTable(HashTable* table, Contact contact) {int index = hashCode(contact.mobile_phone_number_one);HashNode* newNode = (HashNode*)malloc(sizeof(HashNode));newNode->contact = contact;newNode->next = NULL;if (table->table[index] == NULL) {table->table[index] = newNode;}else {HashNode* current = table->table[index];while (current->next != NULL) {current = current->next;}current->next = newNode;}table->length[index]++;
}//2.修改数据
void change(HashTable* table, String contact) {int index = hashCode(contact);HashNode* temp = table->table[index];for (int i = 0; i < table->length[index]; i++) {if (equals(temp->contact.mobile_phone_number_one, contact)) {printf("请输入电话号所属人姓名:");String tempstr;char tempchar[20];scanf("%s", tempchar);tempstr.str = tempchar;tempstr.length = strlen(tempstr.str);if (equals(tempstr, temp->contact.Name)) {change_data(temp);return;}break;}temp = temp->next;}printf("未找到该条记录!\n");
}//3.删除操作
void deleteNode(HashTable* table, String contact) {int index = hashCode(contact);HashNode* temp = table->table[index];HashNode* tempbefore = (HashNode*)malloc(sizeof(HashNode));tempbefore->next = table->table[index];for (int i = 0; i < table->length[index]; i++) {if (equals(temp->contact.mobile_phone_number_one, contact)) {printf("请输入电话号所属人姓名:");String tempstr;char tempchar[20];scanf("%s", tempchar);getchar();tempstr.str = tempchar;tempstr.length = strlen(tempstr.str);if (equals(tempstr, temp->contact.Name)) {if (table->length[index] == 1) {table->table[index] = NULL;table->length[index]--;return;}table->length[index]--;HashNode* tempnode = temp->next;temp = NULL;tempbefore->next = tempnode;return;}break;}temp = temp->next;tempbefore = tempbefore->next;}printf("未找到该条记录!\n");
}//4.遍历显示数据
void display(HashTable table) {for (int i = 0; i < Hash_Length; i++) {if (table.length[i] == 0) {continue;}HashNode* temp = table.table[i];for (int j = 0; j < table.length[i]; j++) {Print(temp->contact);temp = temp->next;}}
}
//界面
void Face(HashTable* table) {char Options = 0;do{Contact contact;String str;printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");printf("联系方式查询系统\n");printf("1.插入数据\n");printf("2.修改数据\n");printf("3.删除数据\n");printf("4.显示数据\n");printf("请进行操作:");scanf("%c", &Options);getchar();printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");switch (Options){case '0':break;case '1':printf("请输入数据:\n");Scanf(&contact);if (!is_true(contact)||contact.mobile_phone_number_one.length!=11) {printf("数据输入有误!\n");continue;}InsertTable(table, contact);break;case '2':printf("请输入想修改的记录的手机号:\n");str.str = (char*)malloc(20 * sizeof(char));scanf("%s", str.str);str.length = strlen(str.str);change(table, str);break;case '3':printf("请输入想删除的记录的手机号:\n");str.str = (char*)malloc(20 * sizeof(char));scanf("%s", str.str);getchar();str.length = strlen(str.str);deleteNode(table, str);break;case '4':display(*table);break;default:printf("输入错误,请重新输入!\n");break;}} while (Options != '0');writeData(*table);
}int main() {HashTable table;CreateTable(&table);Face(&table);return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阶段十-分布式-任务调度

第一章 定时任务概述 在项目中开发定时任务应该一种比较常见的需求&#xff0c;在 Java 中开发定时任务主要有三种解决方案&#xff1a;一是使用JDK 自带的 Timer&#xff0c;二是使用 Spring Task&#xff0c;三是使用第三方组件 Quartz Timer 是 JDK 自带的定时任务工具,其…

感知与认知的碰撞,大模型时代的智能文档处理范式

目录 0 写在前面1 GPT4-V&#xff1a;拓宽文档认知边界2 大语言模型的文档感知缺陷3 大一统文档图像处理范式3.1 像素级OCR任务3.2 OCR大一统模型3.3 长文档理解与应用 4 总结抽奖福利 0 写在前面 由中国图象图形学学会青年工作委员会发起的第十九届中国图象图形学学会青年科学…

二叉排序树的创建、插入、查找和删除【数据结构】

二叉排序树 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它根结点的值。若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它根结点的值。它的左、右树又分为⼆叉排序树 二叉排序树也叫二叉查找树、二叉搜索树 二叉排序树的创建、插入、查找和删除 …

015、控制流运算符match

1. 控制流运算符match Rust中有一个异常强大的控制流运算符&#xff1a;match&#xff0c;它允许将一个值与一系列的模式相比较&#xff0c;并根据匹配的模式执行相应代码。模式可由字面量、变量名、通配符和许多其他东西组成&#xff1b;后文会详细介绍所有不同种类的模式及它…

MySQL中的事务, 特性及应用

事务 1 &#xff09;概述 只有 innodb 引擎支持事务&#xff0c;myisam 是不支持的事务的本质是原子性操作&#xff0c;不可分割&#xff0c;打包多个操作成为一个原子 2 &#xff09;事务的四大特性(ACID) 原子性 Atomicity 原子性是指事务包含的所有操作不可分割要成功一…

ElasticSearch使用Grafana监控服务状态-Docker版

文章目录 版本信息构建docker-compose.yml参数说明 创建Prometheus配置文件启动验证配置Grafana导入监控模板模板说明 参考资料 版本信息 ElasticSearch&#xff1a;7.14.2 elasticsearch_exporter&#xff1a;1.7.0&#xff08;latest&#xff09; 下载地址&#xff1a;http…

C++ 基础知识体系

一&#xff0c;C基础知识体系 基于自己的编程经验搭建的C知识体系 宏声明与定义函数 函数重载函数指针内敛函数默认参数函数对象 面向对象 面向对象与面向过程的区别封装 数据成员成员方法静态成员 继承 单继承多继承虚继承菱形继承 多态 虚函数纯虚函数抽象类 五大原则 单一职…

如何使用 Python+selenium 进行 web 自动化测试?

Selenium是一个自动化测试工具&#xff0c;它可以模拟用户在浏览器中的操作&#xff0c;比如点击、输入、选择等等。它支持多种浏览器&#xff0c;包括Chrome、Firefox、Safari等等&#xff0c;并且可以在多个平台上运行。 安装和配置Selenium 在使用Selenium之前&#xff0c;…

【VTK三维重建-体绘制】第五期 vtkLODProp3D

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ&#xff1a;870202403 前言 本文分享VTK中体绘制中的vtkLODProp3D对象&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴的点赞关注&#xff0c;小易会继续努力分享&#xff0c;一起进步&#xff01; 你的点赞…

机器学习中异常值的处理方式

背景 3Sigma、Z-Score、box plot、Grubbs假设检验四种分布异常值检验方法可以帮助在数据中识别异常值&#xff0c;而在机器学习中&#xff0c;异常值的检测对模型性能和结果的准确性具有重要影响。 3 Sigma法&#xff1a; 原理&#xff1a;通过计算数据的均值和标准差&#xff…

力扣labuladong——一刷day84

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣743. 网络延迟时间 前言 Dijkstra 算法&#xff08;一般音译成迪杰斯特拉算法&#xff09;无非就是一个 BFS 算法的加强版&#xff0c;它们都是从二叉…

(Java企业 / 公司项目)Nacos的怎么搭建多环境配置?(含相关面试题)(二)

上一篇讲了一个单体服务中配置&#xff0c;传统的Nacos配置但是在微服务架构当中肯定都是多环境下配置&#xff0c;比如生产环境&#xff0c;dev测试环境等等。 第一种方式模拟开始&#xff1a; 首先展示在生产环境中nacos如何配置&#xff0c;在模块下新建一个配置文件&…

达梦数据库安装超详细教程(小白篇)

文章目录 达梦数据库一、达梦数据库简介二、达梦数据库下载三、达梦数据库安装1. 解压2. 安装 四、初始化数据库五、DM管理工具 达梦数据库 一、达梦数据库简介 ​ 达梦数据库管理系统是达梦公司推出的具有完全自主知识产权的高性能数据库管理系统&#xff0c;简称DM。 达梦数…

本地站点通过主备冗余专线连接上云

本地站点通过主备冗余专线连接上云 您可以使用两条物理专线以主备方式将本地数据中心IDC&#xff08;Internet Data Center&#xff09;接入阿里云。采用主备接入方式时&#xff0c;正常情况下仅主用线路在进行流量转发。阿里云按照您配置的健康检查的发包时间间隔探测主用线路…

【Midjourney】AI绘画新手教程(一)登录和创建服务器,生成第一幅画作

一、登录Discord 1、访问Discord官网 使用柯學尚网&#xff08;亲测非必须&#xff0c;可加快响应速度&#xff09;访问Discord官方网址&#xff1a;https://discord.com 选择“在您的浏览器中打开Discord” 然后&#xff0c;注册帐号、购买套餐等&#xff0c;在此不做缀述。…

uniapp+echarts开发APP版本教程

需求 需要在uniappecharts展示图表功能&#xff0c;是APP版本&#xff0c;不是小程序。找了好多教程都乱七八糟的&#xff0c;无法实现。以下是效果图 教程 1、安装插件 HBuilder安装echarts插件&#xff0c;插件地址如下。安装完成后在uni_modules/lime-echart文件夹下 ht…

12.2 【Screen配置】khronos模块配置

一,khronos配置配置简介 khronos部分的配置用于指定与Khronos相关的库和参数(例如EGL和WFD库)。 在graphics.conf配置文件中,khronos部分指定GPU和显示驱动程序。只有在系统需要这两种类型的驱动程序之一或两者时,才需要在配置文件中包含此部分。khronos部分由begin khr…

使用169.254开头的IP地址

介绍&#xff1a; 在计算机网络中&#xff0c;当设备无法通过DHCP服务器获取有效的IP地址时&#xff0c;它会尝试使用自动私有IP地址&#xff08;APIPA&#xff09;来分配一个本地链接的IP地址。APIPA地址范围从169.254.0.1到169.254.255.254。这篇文档将介绍关于使用以169.254…

主板部件

▶1.主要部件 主板是计算机的重要部件&#xff0c;主板由集成电路芯片、电子元器件、电路系统、各种总线插座和接口组成&#xff0c;目前主板标准为ATX。主板的主要功能是传输各种电子信号&#xff0c;部分芯片负责初步处理一些外围数据。不同类型的CPU,需要不同主板与之匹配。…

微信小程序+前后端开发学习材料

目录结构 全局文件 1.app.json 文件 用来对微信小程序进行全局配置&#xff0c;决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。文件内容为一个 JSON 对象。 1.1 page用于指定小程序由哪些页面组成&#xff0c;每一项都对应一个页面的 路径&#xff08;含文…