电话号码查询系统的设计与实现
(1)掌握数据结构中的查找、排序等算法相关知识。
(2)掌握 C 或 C++语言中程序设计的方法。
(1)自选存储结构(顺序表或哈希表)实现电话号码表的初始化创建。
(2)编写一个电话号码查询系统,要求有电话号码记录的录入(插入)存储、查 询、删除、打印、排序(顺序表存储结构必须有排序功能,哈希表结构则可以无此功能) 等模块。
这里用的是哈希表的方式书写的,献丑了
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
#include
#include
#include
#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;
}