XM的小窝


 

[C]人均一份之C语言结课作业

需要实现的功能

开发一套班级通讯录,实现以下功能。

1)学生信息:姓名、班级、电话号码、住址。
2)实现功能:信息的添加、修改、查询和删除。
输出通讯录到文件,从文件中读取通讯录

乱胡的流程图

看着脑阔疼的代码

/*
* Email: [email protected]
* author: kanokano
* Project Name: 基于链表的班级通讯录实现
* CreateTime: 2022-03-21
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
#include <string.h>

//链表声明
typedef struct Contact{
    char name[100];
    char className[100];
    char phoneNumber[20]; //电话号不使用int,使用字符数组更方便
    char adress[400];
    //下一个数据的结构体指针,这里使用单向链表
    struct Contact* nextNode;
} Contact;

//全局变量声明
Contact* headNode;  //链表头,应尽量避免修改

//函数声明
Contact* CreateContact(Contact* contactList);
void PrintContact(Contact* contactList);
Contact* DeleteContact(Contact* contactList,int nodeIndex);
Contact* AppendContact(Contact* contactList);
Contact* InsertContact(Contact* contactList, int nodeNumber);
void FindContact(Contact* contactList,char name[]);
void EditContact(Contact* contactList,int nodeNumber);
void PrintToTxt(Contact* contactList);
void ReadTxt(Contact* contactList);
int IsNullOrEmpty(Contact* contactList);
int MainMenu();

/*主程序部分*/
int main(){
    Contact* newContact =NULL;
    char name[100];
    int  index = 0;
    while(1){
        //主菜单界面
        int menuOption = 0;
        menuOption = MainMenu();
        system("cls");
        switch(menuOption){
            case 1:
                newContact = CreateContact(newContact);
                headNode = newContact;
                system("cls");
                break;
            case 2:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                newContact = AppendContact(newContact);
                system("cls");
                break;
            case 3:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                printf("请输入要查询的联系人名称:");
                scanf("%s",name);
                FindContact(newContact,name);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 4:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                printf("请输入要删除的联系人所在的表的序号:");
                scanf("%d",&index);
                newContact =  DeleteContact(newContact,index);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 5:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                printf("请输入要插入的联系人所在的位置:");
                scanf("%d",&index);
                newContact = InsertContact(newContact,index);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 6:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                printf("请输入要修改的联系人所在的位置:");
                scanf("%d",&index);
                EditContact(newContact,index);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 7:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                PrintContact(newContact);
                system("cls");
                break;
            case 8:
                if(IsNullOrEmpty(newContact) == 0)
                    break;
                PrintToTxt(newContact);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 9:
                ReadTxt(newContact);
                fflush(stdin);
                getchar();
                system("cls");
                break;
            case 10:
                exit(0);
        }

    }

    return 0;
}

//创建新表方法,会覆盖掉之前的表 返回一个Contact头表指针
Contact* CreateContact(Contact* contactList){
    //新建并初始化一个节点
    Contact* newContact = (Contact*)malloc(sizeof(Contact));
    newContact -> nextNode = NULL;

    //直接赋值
    contactList = newContact;

    //循环添加节点
    char inputFlag = 'n';
    printf("请输入学生的信息\n");
    while(1){
        //输入信息
        printf("姓名:");
        scanf("%s",newContact->name);
        printf("班级:");
        scanf("%s",newContact->className);
        printf("电话:");
        scanf("%s",newContact->phoneNumber);
        printf("住址:");
        //清空缓冲区
        fflush(stdin);
        gets(newContact->adress);

        //清空缓冲区
        fflush(stdin);

        //提示用户是否继续添加
        printf("添加完成,是否继续添加(Y 继续输入)或按任意键返回主菜单:");
        inputFlag = getchar();

        if(inputFlag == 'Y'||inputFlag == 'y'){
            //清屏
            system("cls");
            //新建节点
            newContact -> nextNode = (Contact*)malloc(sizeof(Contact));
            //节点后移一位,并初始化
            newContact = newContact -> nextNode;
            newContact->nextNode = NULL;
            continue;
        }
        else{
            //清空缓冲区
            fflush(stdin);
            return contactList;
        }

    }

}

//输出信息的方法
void PrintContact(Contact* contactList){

    //循环输出链表
    printf("姓名\t\t班级\t\t电话\t\t住址\n");
    while(contactList != NULL){
        printf("%-12s\t%-12s\t%-12s\t%-6s\n",contactList -> name,contactList -> className, contactList -> phoneNumber,contactList -> adress);
        //后移一位
        contactList  = contactList -> nextNode;
    }

    fflush(stdin);
    printf("输出完毕,按任意键返回");
    getchar();
}

//删除指定序列节点方法,返回一个Contact头表指针
Contact* DeleteContact(Contact* contactList,int nodeIndex){

    //创建一个变量表示当前的节点序号
    int currentIndex = 1;
    //备份头表
    Contact* head = contactList;
    //如果需要删除的下标是第一个
    if(nodeIndex == 1){
        head = contactList->nextNode;
        printf("删除成功!\n");
        return head;
    }
    //遍历节点到最后一个
    while((contactList->nextNode) != NULL){
        //如果找到了需要删除的变量的前一个变量
        if(nodeIndex - 1 == currentIndex){
            contactList -> nextNode = (contactList -> nextNode) -> nextNode;
            printf("删除成功!\n");
            return head;
        }
        contactList = contactList -> nextNode;
        currentIndex++;
    }
    //如果到了最后一个表,则直接将这个表赋值为NULL即可
    if((contactList->nextNode) == NULL && nodeIndex == 1){
        contactList = NULL;
        printf("删除成功!\n");
        return head;
    }

    printf("找不到对应的节点!\n");

    //返回头表
    return head;

}

//追加 返回一个Contact头表指针
Contact* AppendContact(Contact* contactList){

    printf("开始追加节点\n");
    //保存链表头地址
    Contact* head = contactList;

    //循环到尾节点
    while((contactList->nextNode) != NULL){
        contactList = contactList ->nextNode;
    }

    //使用CreateContact创建新表
    contactList -> nextNode = CreateContact(contactList);
    return head;
}

//根据链表序号插入 返回一个Contact头表指针
Contact* InsertContact(Contact* contactList, int nodeNumber){

    //设置一个表示操作状态的变量
    int insertStatus = 1;
    //保存链表头地址
    Contact* head = contactList;
    //记录初始位置
    int currentNumber = 1;

    //如果链表中只有一个节点,或者nodeNumber == 1的话,就直接添加链表到第一个节点的后面
    if(contactList->nextNode == NULL || nodeNumber == 1){
        //如果链表为多个节点,但是添加节点位置是1
        if(nodeNumber == 1 && (contactList-> nextNode != NULL) ){
            //新建一个表
            Contact* newContact = NULL;
            newContact =CreateContact(newContact);

            //保存当前表的后一个节点地址
            Contact* contactListNextNode = contactList -> nextNode;

            //把新建的表插入到当前表的后面
            contactList -> nextNode = newContact;

            //遍历新表到末尾
            while(newContact -> nextNode != NULL){
                newContact = newContact -> nextNode;
            }
            //把新表的表头赋值给当前表的后一个节点
            newContact ->nextNode = contactListNextNode;

        }
        //如果添加的节点的位置是1,也只有一个节点
        else if(nodeNumber == 1 && (contactList->nextNode == NULL) ){
            //直接放到第一个节点的后面
            contactList ->nextNode = CreateContact(contactList);
        }
        else{
            //以上方法无法找到,设插入状态为0
            insertStatus = 0;
        }
    }
    else{
            while(contactList != NULL){
                contactList = contactList -> nextNode;
                currentNumber++;
                //如果循环到了要查找的链表编号,则新建一个表,插入到其中
                if(currentNumber == nodeNumber && contactList != NULL){
                    //新建一个表
                    Contact* newContact = NULL;
                    newContact =CreateContact(newContact);

                    //保存当前表的后一个节点地址
                    Contact* contactListNextNode = contactList -> nextNode;

                    //把新建的表插入到当前表的后面
                    contactList -> nextNode = newContact;

                    //遍历新表到末尾
                    while(newContact -> nextNode != NULL){
                        newContact = newContact -> nextNode;
                    }
                    //把新表的表头赋值给当前表的后一个节点
                    newContact ->nextNode = contactListNextNode;

                    break;
                }

            }
            //以上方法都无法找到,设插入状态为0
            insertStatus = 0;
    }
    //如果无法插入,则提示无效
    if(contactList == NULL || insertStatus == 0){
        printf("您输入的序号无效\n");
    }

    return head;
}

//查找信息方法 返回一个Contact头表指针
void FindContact(Contact* contactList,char name[]){

    // 标记查找状态
    int findSuccess = 0;
    int display = 1;
    //遍历链表
    while(contactList != NULL){
        //匹配符合的名称
        if(strcmp(name,contactList -> name) == 0){
            if(display == 1 ){
                printf("查找成功!!!!!\n");
                printf("姓名\t\t班级\t\t电话\t\t住址\n");
                display = 0;
            }
            printf("%-12s\t%-12s\t%-12s\t%-6s\n",contactList -> name,contactList -> className, contactList -> phoneNumber,contactList -> adress);
            //查找成功
            findSuccess = 1;
        }

        contactList = contactList -> nextNode;
    }
    if(findSuccess == 0){
        printf("查找失败!");
    }
}
//修改联系人 按照序号修改 返回一个Contact头表指针
void EditContact(Contact* contactList,int nodeNumber){

    //标记现有的节点序号
    int currentNumber = 1;

    //遍历链表
    while(contactList != NULL){
        //如果找到该节点,就修改
        if(nodeNumber == currentNumber){
            printf("请输入修改后的姓名:");
            scanf("%s",contactList ->name);
            printf("请输入修改后的班级:");
            scanf("%s",contactList ->className);
            printf("请输入修改后的电话:");
            scanf("%s",contactList ->phoneNumber);
            printf("请输入修改后的地址:");
            //清空缓冲区
            fflush(stdin);
            gets(contactList->adress);
            return;
        }
        contactList = contactList ->nextNode;
        currentNumber++;
    }
    printf("找不到要修改的节点!!!\n");
}
//输出信息到txt文件
void PrintToTxt(Contact* contactList){

    FILE* fp;
    fp = fopen(".\\Contact.txt","w+");
    if(fp == NULL){
        printf("文件打开失败,请检查权限!");
        return;
    }
    fprintf(fp,"姓名\t\t班级\t\t电话\t\t住址\n");
    while(contactList != NULL){
        fprintf(fp,"%-12s\t%-12s\t%-12s\t%-6s\n",contactList -> name,contactList -> className, contactList -> phoneNumber,contactList -> adress);
        contactList = contactList -> nextNode;
    }
    fclose(fp);
    printf("文件保存成功!");
}
//读取txt文件
void ReadTxt(Contact* contactList){

    FILE* fp;
    fp = fopen(".\\Contact.txt","r");
    if(fp == NULL){
        printf("文件打开失败!");
        return;
    }
    char c;
    while((c=fgetc(fp))!=EOF)
        putchar(c);
    fclose(fp);
}
//主菜单界面
int MainMenu(){

    int option = 0;
    system("color 3e");
    system("title Made by MiniKano");
    printf("欢迎使用班级通讯录!\n");
    printf("Made by MiniKano !\n\n");
    printf("1.新建联系人列表\n");
    printf("2.追加联系人\n");
    printf("3.查找联系人\n");
    printf("4.删除联系人\n");
    printf("5.插入联系人\n");
    printf("6.修改联系人\n");
    printf("7.查看现有联系人\n");
    printf("8.导出表到文本文件\n");
    printf("9.读取文本文件\n");
    printf("10.退出\n\n");
    printf("请输入:");
    scanf("%d",&option);
    return option;
}
//判断表是否为空
int IsNullOrEmpty(Contact* contactList){
    if(contactList == NULL){
        printf("原表不存在,请创建一个新表!");
        fflush(stdin);
        getchar();
        system("cls");
        return 0;
    }else{
        return 1;
    }
}

//修改代码页为utf8
//system("chcp 65001");

P.S:所以为什么要在开学的时候结课 :鹿乃_打扰了:

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注