📄 filefunc.c
字号:
#include "mydb.h"
enum {errnosize=50};
char myerr[errnosize]={0};
FILE *fp=NULL;
pfileinfo myfileinfo=NULL;
pstuinfo mystuinfo=NULL;
//本函数设置系统错误,并终止程序
void seterr(char*err)
{
memset((void*)myerr,0,errnosize);
int n=strlen(err);
if(n>errnosize-1)
n=errnosize;
memcpy(myerr,err,n);
printf("\n\n%s\n\n",err);
exit(0);
}
/*本函数用于清理所有全局变量
包括文件指针和全局结构体指针*/
void freeparam()
{
if(fp)fclose(fp);fp=NULL;
if(myfileinfo)free(myfileinfo);
myfileinfo=NULL;
if(mystuinfo)free(mystuinfo);
mystuinfo=NULL;
}
//本函数用于对文件进行操作,将常用的文件操作集于一身
void fcntl(long seek,int cntlmode,void *pdata,int size)
{
if(!fp)fp=fopen(FILEPATH,"rb+");
if(!fp)initfile();
rewind(fp);
fseek(fp,seek,SEEK_SET);
if(!pdata)return;
if(!size)
seterr("fcntl:parameter not matched");
switch(cntlmode)
{
case READ:
fread(pdata,size,1,fp);
break;
case WRITE:
fwrite(pdata,size,1,fp);
break;
default:
seterr("fcntl:cntlmode invalid");
}
}
//初始化数据库
void initfile()
{
if(!fp)fp=fopen(FILEPATH,"wb+");
if(!myfileinfo)myfileinfo=NEW(fileinfo);
memset(myfileinfo,0,FILEINFOSIZE);
myfileinfo->seek[0]=DATASEEK;
strcpy(myfileinfo->key,"macosx");
int i;for(i=0;i<MAXSUBCOUNT;i++)
myfileinfo->sub[i].sub_id=i+1;
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
}
//添加学生
void addstu(pmystu newstuinfo)
{
if(!newstuinfo)
seterr("addstu:newstuinfo null");
if(search(newstuinfo->stu_schid,SEARCH_SCHID))
seterr("addstu:database schid collision");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
int spacecount=myfileinfo->spacecount;
if(spacecount>=MAXSPACECOUNT)
seterr("addstu:parameter invalid");
long seek=myfileinfo->seek[spacecount];
if(spacecount)
{
myfileinfo->seek[spacecount]=0;
myfileinfo->spacecount--;
}
else myfileinfo->seek[spacecount]+=DATATRANS;
if(!mystuinfo)mystuinfo=NEW(stuinfo);
memset(mystuinfo,0,STUINFOSIZE);
memcpy(&(mystuinfo->stu_privacy),newstuinfo,MYSTUSIZE);
mystuinfo->stu_seek=seek;
mystuinfo->flag=1;int i;
mystuinfo->stu_sysid=myfileinfo->countmax+1;
for(i=0;i<MAXSUBCOUNT;i++)
mystuinfo->stu_mark[i].sub_id=i+1;
fcntl(seek,WRITE,mystuinfo,STUINFOSIZE);
myfileinfo->stucount++;
myfileinfo->countmax++;
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
}
//删除学生
void delstu(long delstuseek)
{
if(delstuseek<DATASEEK)
seterr("delstu:parameter zero");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
if(!mystuinfo)mystuinfo=NEW(stuinfo);
memset(mystuinfo,0,STUINFOSIZE);
fcntl(delstuseek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag)seterr("delstu:parameter invalid");
mystuinfo->flag=0;
fcntl(delstuseek,WRITE,mystuinfo,STUINFOSIZE);
myfileinfo->stucount--;
myfileinfo->spacecount++;
int count=myfileinfo->spacecount;
if(count<MAXSPACECOUNT)
myfileinfo->seek[count]=delstuseek;
else myfileinfo->spacecount--;
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
}
//编辑一个已存在学生
void editstu(long editstuseek,pmystu tempstu)
{
if(!tempstu||editstuseek<DATASEEK)
seterr("editstu:parameter null");
if(!mystuinfo)mystuinfo=NEW(stuinfo);
memset(mystuinfo,0,STUINFOSIZE);
fcntl(editstuseek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag)
seterr("editstu:editstu invalid");
plink linkhead=search(tempstu->stu_schid,SEARCH_SCHID);
if(linkhead&&linkhead->data-editstuseek)
seterr("editstu:database schid collision");
memcpy(&mystuinfo->stu_privacy,tempstu,MYSTUSIZE);
fcntl(editstuseek,WRITE,mystuinfo,STUINFOSIZE);
}
//添加新的学科
void addsub(psubinfo newsub)
{
if(!newsub)seterr("addsub:parameter null");
if(newsub->sub_term<1||newsub->sub_term>8)
seterr("addsub:parameter invalid");
if(newsub->sub_rate<0.5||newsub->sub_rate>6)
seterr("addsub:parameter invalid");
if(search(newsub->sub_name,SEARCH_SUB))
seterr("addsub:database sub collision");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
int subcount=myfileinfo->subcount;
if(subcount>=MAXSUBCOUNT)
seterr("addsub:subject full");
psubinfo psubtemp=myfileinfo->sub;
newsub->flag=1;int i;
for(i=0;i<MAXSUBCOUNT;i++,psubtemp++)
if(!psubtemp->flag)
{
newsub->sub_id=psubtemp->sub_id;
memcpy(psubtemp,newsub,SUBINFOSIZE);
break;
}
if(i>=MAXSUBCOUNT)
seterr("addsub:subject all in use");
myfileinfo->subcount++;
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
}
//删除一个已经存在学科
void delsub(int subid)
{
if(subid<1||subid>MAXSUBCOUNT)
seterr("delsub:subid invalid");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
if(myfileinfo->subcount<=0)
seterr("delsub:subcount zero");
psubinfo subtemp=myfileinfo->sub+subid-1;
if(!subtemp->flag)seterr("delsub:flag invalid");
subtemp->flag=0;myfileinfo->subcount--;
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
if(!mystuinfo)mystuinfo=NEW(stuinfo);
long seek=DATASEEK;int i;psubmark marktemp=NULL;
for(i=0;i<myfileinfo->stucount;i++,seek+=DATATRANS)
{
fcntl(seek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag){i--;continue;}
marktemp=mystuinfo->stu_mark+subid-1;
if(marktemp->flag)
{
memset(marktemp,0,SUBMARKSIZE);
mystuinfo->stu_markcount--;
}
else continue;
fcntl(seek,WRITE,mystuinfo,STUINFOSIZE);
makeavemark(seek);
}
}
//编辑一个已经存在的学科
void editsub(psubinfo newsub)
{
if(!newsub)
seterr("editsub:newsub null");
if(!newsub->flag)
seterr("editsub:newsub invalid");
int subid=newsub->sub_id;
if(subid<1||subid>MAXSUBCOUNT)
seterr("editsub:subid invalid");
int term=newsub->sub_term;
if(term<1||term>8)
seterr("editsub:subterm invalid");
double rate=newsub->sub_rate;
if(rate<0.5||rate>6)
seterr("editsub:subrate invalid");
int size=strlen(newsub->sub_name);
if(size>=20)newsub->sub_name[19]=0;
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
plink linkhead=search(newsub->sub_name,SEARCH_SUB);
if(linkhead&&linkhead->next)
seterr("editsub:search invalid");
if(linkhead&&linkhead->data-subid)
seterr("editsub:database sub collision");
newsub->flag=1;
psubinfo subtemp=myfileinfo->sub+subid-1;
memcpy(subtemp,newsub,SUBINFOSIZE);
fcntl(0,WRITE,myfileinfo,FILEINFOSIZE);
if(!mystuinfo)mystuinfo=NEW(stuinfo);
int count=myfileinfo->stucount;
int i;long seek=DATASEEK;
for(i=0;i<count;i++,seek+=DATATRANS)
{
fcntl(seek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag){i--;continue;}
makeavemark(seek);
}
}
//编辑某学生某科目
void editmark(psubmark newmark,long stuseek)
{
if(!newmark||stuseek<DATASEEK)
seterr("addmark:parameter null");
int subid=newmark->sub_id;
if(subid<-1||subid>MAXSUBCOUNT||!subid)
seterr("editmark:subid invalid");
double mark=newmark->sub_mark;
if(mark<0||mark>100)
seterr("editmark:submark invalid");
if(!mystuinfo)mystuinfo=NEW(stuinfo);
memset(mystuinfo,0,STUINFOSIZE);
fcntl(stuseek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag)
seterr("editmark:student invalid");
psubmark marktemp=mystuinfo->stu_mark+subid-1;
int flag1=marktemp->flag,flag2=newmark->flag;
if(!flag1&&!flag2)
seterr("editmark:markflag invalid");
memcpy(marktemp,newmark,SUBMARKSIZE);
if(!flag1&&flag2)mystuinfo->stu_markcount++;
if(flag1&&!flag2)mystuinfo->stu_markcount--;
fcntl(stuseek,WRITE,mystuinfo,STUINFOSIZE);
makeavemark(stuseek);
}
//计算某学生的加权分数
void makeavemark(long stuseek)
{
if(stuseek<DATASEEK)
seterr("makeavemark:parameter invalid");
if(!mystuinfo)mystuinfo=NEW(stuinfo);
memset(mystuinfo,0,STUINFOSIZE);
fcntl(stuseek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag)
seterr("makeavemark:stuinfo invalid");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
int subcount=myfileinfo->subcount;
if(!subcount||!mystuinfo->stu_markcount)
{
mystuinfo->stu_avemark=0;
fcntl(mystuinfo->stu_seek,WRITE,mystuinfo,STUINFOSIZE);
return;
}
psubinfo subtemp=myfileinfo->sub;
psubmark marktemp=mystuinfo->stu_mark;
int i;double marksum=0.0,rate,ratesum=0.0;
for(i=0;i<subcount;i++,subtemp++,marktemp++)
{
if(!subtemp->flag){i--;continue;}
if(!marktemp->flag)continue;
rate=subtemp->sub_rate;
ratesum+=rate;
marksum+=marktemp->sub_mark*rate;
}
if(ratesum<0.1||marksum<0.1)mystuinfo->stu_avemark=0;
else mystuinfo->stu_avemark=marksum/ratesum;
fcntl(mystuinfo->stu_seek,WRITE,mystuinfo,STUINFOSIZE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -