1、想实现的功能是什么:
1)设计菜单
(2)1==========》添加影片
2==========》删除影片
3==========》修改影片
4==========》查找影片
5==========》显示所有影片
6==========》退出
(3)每一模块封装成一个函数
(4)影片编号不允许重复
(5) 数据结构 : 数组存储
(6) 将数据存储在文件里面,下次运行程序进行读操作,
将写入操作,与读操作封装成独立的函数。
编程思路:这里面需要运用到结构体的知识,函数的封装,以及文件的读写操作。包括结构体数组的知识。
一、首先我们可以从简单的主体部分做起,先把框架搭起来。
#include <stdio.h>
#include "film.h"
int main()
{
struct film_info f[NUM];
int sel;
int flag = 1;
int count = 0 ; //影片的初始值
count= my_read(f,NUM); //读取数据后影片的数量
printf("===>目前有%d部影片信息<===\n",count);
while(flag)
{
printf("1、***添加影片信息*******\n");
printf("2、***删除影片信息*******\n");
printf("3、***修改影片信息*******\n");
printf("4、***显示所有影片信息***\n");
printf("5、***查找影片信息*******\n");
printf("0、***退出系统***********\n");
printf("请输入你的选择:");
scanf("%d", &sel);
while(getchar()!='\n');
switch(sel)
{
case 1:
add_film_info(f, &count);
break;
case 2:
del_film_info(f, &count);
break;
case 3:
mod_film_info(f, count);
break;
case 4:
show_film_info(f, count);
break;
case 5:
find_film_info(f, count);
break;
case 0:
flag = 0;
break;
default:
printf("输入有误,请重新选择!\n");
break;
}
}
mywrite(f,count);
return 0;
}
我们可以看到,这里是运用了switch分支结构来进行菜单的选择,将上面的功能分为几个模块,后面封装好函数后直接进行调用。
二、开始编写需要用到的函数,并封装起来。
#include <stdio.h>
#include "film.h"
struct film_info
{
int id;
char name[32];
char director[32];
int time;
};
int mywrite(struct film_info f[],int count)//文本写入文件函数
{
FILE *fp=NULL;
fp=fopen("./info.txt","w");// 1、打开文件
if(NULL==fp)
{
perror("fopen");
return -1;
}
int i,ret,j=0;
for(int i=0;i<count;i++){ //2、进行写入操作
ret=fprintf(fp,"%d %s %s %d\n",f[i].id,f[i].name,f[i].director,f[i].time);
j++;
}
if(ret<0){ //fprintf的返回值小于0,读取结束。
perror("fwrite");
fclose(fp);
return -1;
}
fclose(fp);//3、关闭文件
printf("录入数据成功\n");
return j;
}
int my_read(struct film_info f[],int count){
/*读取数据函数*/
FILE *fp=NULL;
/*打开文件*/
fp=fopen("./info.txt","r");
if(NULL==fp)
{
perror("fopen");
return -1;
}
/*进行读操作*/
int ret=0,i=0,j=0;
for(i=0;i<count;i++){
ret=fscanf(fp,"%d%s%s%d",&f[i].id,f[i].name,f[i].director,&f[i].time);
j++;
/*ret为-1也就是EOF说明读取到文件末尾了,代表可以结束读操作了*/
if(ret==EOF){
break;
}
}
/*关闭文件*/
fclose(fp);
return j-1;//j-1因为最后一次没读到数据可是j也加1了,所以实际读到的就是j-1个信息
/*返回值就是读取到的影片个数,很重要!!!回头可控制count的初始值*/
}
void add_film_info(struct film_info f[], int *pcount)
{
if(*pcount > NUM)
{
printf("内存已满,添加失败!\n");
return ;
}
struct film_info t;
static int id = 1000;
int j=0;
for(int i=0;i<*pcount;i++){ /*此处用来判断已经有多少部影片信息*/
if(0!=f[i].id){
j++;
}
}
t.id = id+j;//让id等于最后一个的编号
/*此处用来判断是否有重复,有的话编号加一,保证不会重复*/
for(int i=0;i<*pcount;i++){
if(t.id==f[i].id){
t.id=t.id+1;
}
}
// id ++;改动后,实际上不需要静态变量了
printf("请输入影片名称:");
scanf("%s", t.name);
while(getchar()!='\n');
printf("请输入影片的导演:");
scanf("%s", t.director);
while(getchar()!='\n');
printf("请输入影片时长:");
scanf("%d", &t.time);
while(getchar()!='\n');
f[*pcount] = t;
(*pcount) ++;//影片总量记得自增。
printf("添加影片信息成功!\n");
return ;
}
void show_film_info(struct film_info f[], int count)
{
if(count == 0)
{
printf("暂无影片信息!\n");
return ;
}
printf("编号\t名称\t导演\t时长\n");
for(int i=0; i<count; i++)
{
printf("%d\t%s\t%s\t%d\n", f[i].id, f[i].name, f[i].director, f[i].time);
}
}
// 查找失败: -1
// 查找成功: 返回对应的下标
int find_film_info_by_id(struct film_info f[], int count, int id)
{
for(int i=0; i<count; i++)
{
if(f[i].id == id)
{
return i;
}
}
return -1;
}
void find_film_info(struct film_info f[], int count)
{
int id;
printf("请输入查找的影片编号:");
scanf("%d", &id);
while(getchar()!='\n');
int index = find_film_info_by_id(f, count, id);
if(index<0)
{
printf("影片编号为 %d 不存在!\n", id);
}
else
{
printf("编号为%d影片信息如下:\n", id);
printf("名称: %s\n", f[index].name);
printf("导演: %s\n", f[index].director);
printf("时长: %d\n", f[index].time);
}
return ;
}
void del_film_info(struct film_info f[], int *pcount)
{
int id;
printf("请输入删除的影片编号:");
scanf("%d", &id);
while(getchar()!='\n');
int index = find_film_info_by_id(f, *pcount, id);
if(index < 0)
{
printf("编号不存在,删除失败!\n");
return ;
}
for(int j= index+1; j<*pcount; j++)
{
f[j-1] = f[j];
}
(*pcount) --;
printf("删除成功!\n");
return ;
}
void mod_film_info(struct film_info f[], int count)
{
int id;
printf("请输入修改的影片编号:");
scanf("%d", &id);
while(getchar()!='\n');
int index = find_film_info_by_id(f, count, id);
if(index<0)
{
printf("修改失败,编号不存在!\b");
return ;
}
int flag = 1;
int sel;
while(flag)
{
printf("1、名称 2、导演 3、时长 0、返回上一层\n");
printf("请输入修改选项:");
scanf("%d", &sel);
while(getchar()!='\n');
switch(sel)
{
case 1:
printf("请输入新的影片名称:");
scanf("%s", f[index].name);
while(getchar()!='\n');
break;
case 2:
printf("请输入新的影片导演:");
scanf("%s", f[index].director);
while(getchar()!='\n');
break;
case 3:
printf("请输入新的影片时长:");
scanf("%d", &f[index].time);
while(getchar()!='\n');
break;
case 0:
flag = 0;
break;
default:
printf("输入有误,请重新选择!\n");
break;
}
}
}
上面就是我们封装好的函数,
为了程序的独立性,可以创建名字相同的.c .h来保存他们。
//函数的头文件
#include <stdio.h>
#include "tooler.h"
#define NUM 10
void add_film_info(struct film_info f[], int *pcount);
void show_film_info(struct film_info f[], int count);
// 查找失败: -1
// 查找成功: 返回对应的下标
int find_film_info_by_id(struct film_info f[], int count, int id);
void find_film_info(struct film_info f[], int count);
void del_film_info(struct film_info f[], int *pcount);
void mod_film_info(struct film_info f[], int count);
可以用Makefile来联合编译
src = $(wildcard ./*.c) #获取当前路径下所有的 .c文件
obj = $(patsubst %.c, %.o, $(src)) #将 .c 文件转换成 .o
target = app
$(target): $(obj)
gcc $^ -o $@
%.o : %.c
gcc $^ -o $@ -c
clean:
rm -rf *.o $(target)
好了,以上就是一个简单的影片信息管理系统了。
看一下效果图吧