利用链表和指针进行简单的图书管理系统的编程。
简单的效果图如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//菜单
void menu()//定义菜单函数
{
printf("--------------------------图书管理系统--------------------------\n");
printf("\t\t1.录入图书信息\n");
printf("\t\t2.查找图书信息\n");
printf("\t\t3.删除图书信息\n");
printf("\t\t4.浏览图书信息\n");
printf("\t\t5.退出图书管理系统\n");
printf("----------------------------------------------------------------\n");
}
//函数声明
void printList(struct Node* headNode);
void insertNodeByHead(struct Node* headNode, struct Book data);
struct Node* createList();
void deleteAppointNode(struct Node* headNode, char* title);
struct Node* searchInfoByData(struct Node* headNode, char* title);
//定义结构体
struct Book
{
char title[128];
char auther[20];
char press[128];
};
//定义结构体指针
struct Node
{
struct Book data;
struct Node* next;
};
struct Node* createList()
{
//结构体变量表示表头,动态内存申请
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->next = NULL;//数据域data不做初始化
return headNode;
}
//创建节点
struct Node* createNode(struct Book data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//插入节点
void insertNodeByHead(struct Node* headNode, struct Book data)
{
struct Node* newNode = createNode(data);
//表头法插入
newNode->next = headNode->next;
headNode->next = newNode;
}
//指定位置删除
void deleteAppointNode(struct Node* headNode, char* title)//指定用书籍名进行查找
{
struct Node* posNode = headNode->next;
struct Node* posFrontNode = headNode;
if (posNode == NULL)
{
printf("数据为空,无法删除!\n");
return;
}
//name是字符串,无法直接比较,用strcmp进行拆分到数据比较
while (strcmp(posNode->data.title, title))
{
posFrontNode = posNode;
posNode = posFrontNode->next;
if (posNode == NULL)
{
printf("未找到指定位置无法删除!\n");
return;
}
}
//找到的话
posFrontNode->next = posNode->next;
free(posNode);
}
//查找功能
struct Node* searchInfoByData(struct Node* headNode, char* title)
{
struct Node* pMove = headNode->next;
if (pMove == NULL)
return NULL;
if (strcmp(pMove->data.title, title) != 0)
{
return NULL;
}
while (strcmp(pMove->data.title, title))
{
pMove = pMove->next;
}
return pMove;
}
//文件读操作
void readInfoFromFile(struct Node* headNode,const char* fileName)
{
//打开文件
FILE* fp;
struct Book data;
fp = fopen(fileName, "r");
if (fp == NULL)
{
fp=fopen (fileName, "w+");
}
//读文件
while (fscanf(fp, "%s\t%s\t%s\n", data.auther, data.title, data.press)!=EOF)
{
insertNodeByHead(headNode, data);
}
//关闭文件
fclose(fp);
}
//文件写操作
void writeInfoToFile(struct Node* headNode,const char* fileName)
{
FILE* fp;
fp = fopen(fileName, "w");
struct Node* pMove = headNode->next;
while (pMove)
{
fprintf(fp, "%s\t%s\t%s\n", pMove->data.auther, pMove->data.title, pMove->data.press);
pMove = pMove->next;
}
fclose(fp);
}
//打印链表
void printList(struct Node* headNode)
{
struct Node* pMove = headNode->next;
//数据的处理
printf("作者\t\t书名\t\t出版社\n");
while (pMove)
{
printf("%s\t\t%s\t\t%s\n", pMove->data.auther, pMove->data.title, pMove->data.press);
pMove = pMove->next;
}
printf("\n");
}
//创建新的链表
struct Node* list = createList();
//用户的交互,选取相应的菜单
void keyDown()
{
int choice = 0;
struct Book data;
struct Node* pMove = NULL;
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("----------------------录入信息---------------------------\n");
//插入链表
printf("请输入作者姓名、书名、出版社:(用空格隔开)\n");
fflush(stdin); //清空缓冲区
scanf("%s%s%s", data.auther, data.title, data.press);
insertNodeByHead(list, data);
break;
case 2:
printf("----------------------查找信息---------------------------\n");
printf("请输入要查找的书籍名:");
scanf("%s", data.title);
pMove = searchInfoByData(list, data.title);
if (pMove == NULL)
{
printf("没有这个名字鸭!\n");
system("pause");
}
else
{
printf("作者\t\t书名\t\t出版社\n");
printf("%s\t\t%s\t\t%s\n", pMove->data.auther, pMove->data.title, pMove->data.press);
}
break;
case 3:
printf("----------------------删除信息---------------------------\n");
printf("请输入要删除的书籍名:");
scanf("%s", data.title);
deleteAppointNode(list, data.title);
break;
case 4:
printf("----------------------浏览信息---------------------------\n");
printList(list);//打印链表
break;
case 5:
printf("正常退出系统\n");
system("pause");
exit(0);
break;
default:
printf("输入指令错误\n");
system("pause");
break;
}
writeInfoToFile(list, "1.txt");
}
//链表实现数据的增删改查
int main()
{
readInfoFromFile(list, "1.txt");
while (1)
{
menu();
keyDown();
system("pause");//防止闪屏
system("cls");//清屏函数
}
system("pause");
return 0;
}