上周我做了一个简易版的电影院管理系统,内容包括链表的创建,链表节点的增加、删除、修改、查找。
此电影系统还包含了文件的操作,例如将链表中的数据存到文件中去,也可将文件中的数据赋给链表。
先定义一个链表的结点(因为链表结点需多次使用,所以将其定义在头文件中):
#ifndef _STRUCT_H_
#define _STRUCT_H_
typedef struct Node{
int number;
char name[20];
char date[20];
char time[20];
int price;
int people;
struct Node *next;
}LinkList;
#endif
(将其后缀需改成.h)
这是将链表中的数据存放到文件中:
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
void enter_file(LinkList *head)
{
FILE *fp;
LinkList *p;
p = head->next;
fp = fopen("D:\\电影院管理系统\\电影信息.txt","wt");
if(!fp){
printf("打开文件失败!\n");
exit(1);
}
while(p){
fprintf(fp,"%d %s %s %s %d %d\n",p->number,p->name,p->date,p->time,p->price,p->people);
p = p->next;
}
fclose(fp);
}
这是将文件中的数据存放到链表当中:
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
LinkList *file_to_link()
{
LinkList *head, *p, *temp;
head = (LinkList *)malloc(sizeof(LinkList));
head->next = NULL;
temp = head;
FILE *fp;
fp = fopen("D:\\电影院管理系统\\电影信息.txt","rt");
if(!fp){
printf("打开文件失败!\n");
printf("按任意键进入菜单!\n");
getch();
return NULL;
}
while(!feof(fp)){
p = (LinkList *)malloc(sizeof(LinkList));
fscanf(fp,"%d %s %s %s %d %d\n",&p->number,p->name,p->date,p->time,&p->price,&p->people);
//此处需加上\n,如果不加,将会在文件中出现乱码
temp->next = p;
temp = p;
temp->next = NULL;
}
fclose(fp);
return head;
}
这里将注册信息存放到文件中,同时在登陆时从文件中调取(此处只能存放一个人的信息)。
注册:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void register_()
{
printf("请输入用户名:");
char s[20];
scanf("%s",s);
printf("请输入密码:");
char a[20],p[20];
int i = 0;
do{
a[i] = getch();
if(a[i] == '\r') break;
if(a[i] == '\b'){
if(!i){
printf("\a");
continue;
}
i = i -1;
printf("\b");
}
else{
i = i + 1;
printf("*");
}
}while(a[i] != '\n');
a[i] = '\0';
i = 0;
printf("\n");
printf("请确认密码:");
do{
p[i] = getch();
if(p[i] == '\r') break;
if(p[i] == '\b'){
if(!i){
printf("\a");
continue;
}
i = i -1;
printf("\b");
}
else{
i = i + 1;
printf("*");
}
}while(p[i] != '\n');
p[i] = '\0';
i = 0;
printf("\n");
while(strcmp(a,p)){
printf("请重新确认密码:");
i = 0;
do{
p[i] = getch();
if(p[i] == '\r') break;
if(p[i] == '\b'){
if(!i){
printf("\a");
continue;
}
i = i -1;
printf("\b");
}
else{
i = i + 1;
printf("*");
}
}while(p[i] != '\n');
p[i] = '\0';
printf("\n");
}
printf("注册成功!请登录:\n");
FILE *fp;
fp = fopen("D:\\电影院管理系统\\信息.txt","w");
fprintf(fp,"%s %s",s,a);
fclose(fp);
}
登录:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void login()
{
char s[20];
char a[20];
FILE *fp;
fp = fopen("D:\\电影院管理系统\\信息.txt","rt");
fscanf(fp,"%s %s",s,a);
fclose(fp);
char s1[20];
char a1[20];
printf("请输入用户名:");
scanf("%s",s1);
while(strcmp(s,s1)){
printf("用户名不正确,请重新输入:\n");
scanf("%s",s1);
}
printf("请输入密码:");
//scanf("%s",a1);
int i = 0;
char p[20];
do{
p[i] = getch();
if(p[i] == '\r') break;
if(p[i] == '\b'){
if(!i){
printf("\a");
continue;
}
i = i -1;
printf("\b");
}
else{
i = i + 1;
printf("*");
}
}while(p[i] != '\n');
p[i] = '\0';
printf("\n");
i = 0;
while(strcmp(a,p)){
printf("密码不正确,请重新输入:");
i = 0;
do{
p[i] = getch();
if(p[i] == '\r') break;
if(p[i] == '\b'){
if(!i){
printf("\a");
continue;
}
i = i -1;
printf("\b");
}
else{
i = i + 1;
printf("*");
}
}while(p[i] != '\n');
p[i] = '\0';
printf("\n");
}
}
上面是一个简单的模仿密码输入,但有一点小问题,就是光标回退时*不消失,我也不知道该如何解决。
使用尾插法创建链表,录入电影信息,然后将链表中的信息通过enter_file()函数存放到文件中去(文件是在之前建好的)。
#include<stdio.h>
#include<stdlib.h>
#include "struct.h"
#include<conio.h>
void Enter_system()
{
LinkList *head, *p, *temp;
head = (LinkList *)malloc(sizeof(LinkList));
head->next = NULL;
p = head;
printf("请输入需要录入信息的个数:");
int sum,i;
scanf("%d",&sum);
for ( i = 0;i < sum ; i++){
temp = (LinkList *)malloc(sizeof(LinkList));
printf("请输入编号:");
scanf("%d",&temp->number);
printf("请输入电影名:");
scanf("%s",temp->name);
printf("请输入电影日期:");
scanf("%s",temp->date);
printf("请输入播放时间:");
scanf("%s",temp->time);
printf("请输入影片价格:");
scanf("%d",&temp->price);
printf("请输入观看人数:");
scanf("%d",&temp->people);
p->next = temp;
temp->next = NULL;
p = temp;
temp = NULL;
}
enter_file(head);
printf("按任意键返回菜单!\n");
getch();
}
将之前文件中的数据通过file_to_link()函数存到链表中,然后对链表进行操作。
#include<stdio.h>
#include<stdlib.h>
#include "struct.h"
#include<conio.h>
void Change_system()
{
LinkList *head, *p;
head = file_to_link();
p = head->next;
int a;
printf("请输入需要修改的电影编号:");
scanf("%d",&a);
while(p->number != a && p != NULL){
p = p->next;
}
if(p == NULL){
printf("ERROR!\n");
printf("请重新输入!");
Change_system();
}
printf("请输入修改后的电影名:");
scanf("%s",p->name);
printf("请输入修改后的电影日期:");
scanf("%s",p->date);
printf("请输入修改后的播放时间:");
scanf("%s",p->time);
printf("请输入修改后的影片价格:");
scanf("%d",&p->price);
printf("请输入修改后的观看人数:");
scanf("%d",&p->people);
enter_file(head);
printf("按任意键返回菜单!\n");
getch();
}
链表节点的删除就是先找到链表中所要删除的节点,然后对其操作。
如果链表中没有头节点,可以给其添加一个头结点,有了头节点,方便操作链表的第一个结点。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
void Delete_system()
{
LinkList *head, *p, *temp;
head = file_to_link();
p = head;
int a;
printf("请输入你所要删除的编号:");
scanf("%d",&a);
while(p->next->number != a && p->next != NULL){
p = p->next;
}
if(!p->next && p->number != a){
printf("请输入正确的序号!\n");
Delete_system();
}
else{
temp = p->next;
p->next = temp->next;
temp->next = NULL;
free(temp);
enter_file(head);
printf("按任意键返回菜单!\n");
getch();
}
}
这个有点多余,因为删除结点时就已经查找过结点,但这个功能是不可以省略的。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<string.h>
#include<conio.h>
void Inquire_system()
{
LinkList *head, *p, *temp;
head = file_to_link();
p = head->next;
int a;
printf("请输入需要查询的电影编号:");
scanf("%d",&a);
while(p){
if(a == p->number) {
printf("编号:%d\n",p->number);
printf("名称:%s\n",p->name);
printf("日期:%s\n",p->date);
printf("时间:%s\n",p->time);
printf("价格:%d\n",p->price);
printf("人数:%d\n",p->people);
printf("请按任意键进入菜单!\n");
getch();
break;
}
p = p->next;
}
if(!p){
printf("未找到该电影!\n");
printf("请按任意键进入菜单!\n");
getch();
}
}
排序是数据结构中非常重要的部分,也是不可忽略的部分。
这里我使用直接插入法对链表进行排序。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
void Sort_system()
{
int a;
printf("请选择需要排序的内容:\n");
printf("1.价格\t\t2.人数.\n");
scanf("%d",&a);
if(!(a-1)){
LinkList *head;
head = file_to_link();
if(!head || !head->next)
enter_file(head);
else{
LinkList *temp, *a, *b, *p;
a = head;
p = head->next;
b = p->next;
while(b){
a = head;
while(a->next->price <= b->price && a->next != b){
a = a->next;
}
if(a->next == b) p = p->next;
if(a->next->price > b->price){
p->next = b->next;
b->next = a->next;
a->next = b;
}
b = p->next;
}
enter_file(head);
}
printf("请按任意键返回菜单!\n");
getch();
}
else if(!(a-2)){
LinkList *head;
head = file_to_link();
if(!head || !head->next)
enter_file(head);
else{
LinkList *temp, *a, *b, *p;
a = head;
p = head->next;
b = p->next;
while(b){
a = head;
while(a->next->people <= b->people && a->next != b){
a = a->next;
}
if(a->next == b) p = p->next;
if(a->next->people > b->people){
p->next = b->next;
b->next = a->next;
a->next = b;
}
b = p->next;
}
enter_file(head);
}
printf("按任意键进入菜单!\n");
getch();
}
else{
printf("ERROR!\n");
printf("输入不正确,请重新输入:");
Sort_system();
}
}
这是统计链表长度的函数。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
void Statistics_system()
{
LinkList *head, *temp;
head = file_to_link();
temp = head;
int i = 0;
while(temp->next){
temp = temp->next;
i++;
}
printf("电影个数为:");
printf("%d",i);
printf("\n请按任意键返回菜单!\n");
getch();
}
这里我将链表的插入分为了头插、尾插、和中间的插入。但其核心思想是一样的。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
void Insert_system()
{
LinkList *head, *p, *temp;
head = file_to_link();
temp = head;
printf("请选择插入的地方:");
printf("1.开头 2.末尾 3.中间\n");
int a;
scanf("%d",&a);
if(!(a-1)){
p = (LinkList *)malloc(sizeof(LinkList));
p->next = temp->next;
temp->next = p;
temp = p;
printf("请输入需要插入的信息:\n");
printf("编号:");
scanf("%d",&temp->number);
printf("名称:");
scanf("%s",temp->name);
printf("日期:");
scanf("%s",temp->date);
printf("时间:");
scanf("%s",temp->time);
printf("价格:");
scanf("%d",&temp->price);
printf("人数:");
scanf("%d",&temp->people);
enter_file(head);
printf("请按任意键返回菜单!\n");
getch();
return ;
}
else if(!(a-2)){
while(temp->next){
temp = temp->next;
}
p = (LinkList *)malloc(sizeof(LinkList));
p->next = temp->next;
temp->next = p;
temp = p;
printf("请输入需要插入的信息:\n");
printf("编号:");
scanf("%d",&temp->number);
printf("名称:");
scanf("%s",temp->name);
printf("日期:");
scanf("%s",temp->date);
printf("时间:");
scanf("%s",temp->time);
printf("价格:");
scanf("%d",&temp->price);
printf("人数:");
scanf("%d",&temp->people);
enter_file(head);
printf("请按任意键返回菜单!\n");
getch();
return ;
}
else if(!(a-3)){
printf("请输入你所要插入位置的编号(插入其后):");
int t;
scanf("%d",&t);
temp = head->next;
while(temp->number - t && temp != NULL){
temp = temp->next;
}
if(!temp){
printf("ERROR!");
printf("请按任意键返回菜单!\n");
getch();
return ;
}
p = (LinkList *)malloc(sizeof(LinkList));
p->next = temp->next;
temp->next = p;
temp = p;
printf("请输入需要插入的信息:\n");
printf("编号:");
scanf("%d",&temp->number);
printf("名称:");
scanf("%s",temp->name);
printf("日期:");
scanf("%s",temp->date);
printf("时间:");
scanf("%s",temp->time);
printf("价格:");
scanf("%d",&temp->price);
printf("人数:");
scanf("%d",&temp->people);
enter_file(head);
printf("按任意键返回菜单!\n");
getch();
return ;
}
else{
printf("ERROR!");
printf("按任意键返回菜单!\n");
getch();
}
}
最后就是链表的遍历了。链表的遍历就是用一个指针将链表从第一个开始,一直指到最后一个就结束了。
#include<stdio.h>
#include<stdlib.h>
#include"struct.h"
#include<conio.h>
void Print_system()
{
LinkList *head, *p;
head = file_to_link();
p = head->next;
while(p){
printf("编号:%d\n",p->number);
printf("名称:%s\n",p->name);
printf("日期:%s\n",p->date);
printf("时间:%s\n",p->time);
printf("价格:%d\n",p->price);
printf("人数:%d\n",p->people);
p = p->next;
}
printf("请按任意键返回菜单!\n");
getch();
}
此次写了这个简易的电影院管理系统让我受益匪浅,学习了文件的操作,巩固了链表的操作,完善了我的一些不足,使我进步。我希望在今后的学习中更上一层楼。