需要实现的功能
开发一套班级通讯录,实现以下功能。
1)学生信息:姓名、班级、电话号码、住址。
2)实现功能:信息的添加、修改、查询和删除。
输出通讯录到文件,从文件中读取通讯录
乱胡的流程图
看着脑阔疼的代码
/*
* Email: kanoqwq@qq.com
* 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:所以为什么要在开学的时候结课