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

发布时间:2024年01月04日

实验项目名称:

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

实验目的与要求:

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;
}

?

文章来源:https://blog.csdn.net/2301_77523019/article/details/135397586
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。