⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filefunc.c

📁 sql数据库的实现
💻 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 + -