📄 extrafunc.c
字号:
#include "mydb.h"
/*本函数承担着数据库的所有搜索任务
包括由组名搜索组的ID,由学生的姓名和学号搜索学生,
并返回该生在文件中的偏移地址*/
plink search(char *pdata,int searchtype)
{
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
plink linkhead=NULL,linktemp=NULL;
if(searchtype==SEARCH_SUB)
{
psubinfo subtemp=myfileinfo->sub;int i;
for(i=0;i<MAXSUBCOUNT;i++,subtemp++)
if(subtemp->flag&&!strcmp(subtemp->sub_name,pdata))
{
linkhead=NEW(link);memset(linkhead,0,LINKSIZE);
linkhead->data=subtemp->sub_id;
linkhead->next=NULL;
}
return linkhead;
}
if(strlen(pdata)>=19)pdata[19]=0;
if(!mystuinfo)mystuinfo=NEW(stuinfo);
long seek=DATASEEK;
int count=myfileinfo->stucount,i;
for(i=0;i<count;i++,seek+=DATATRANS)
{
memset(mystuinfo,0,STUINFOSIZE);
fcntl(seek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag){i--;continue;}
pmystu stutemp=&mystuinfo->stu_privacy;
switch(searchtype)
{
case SEARCH_SCHID:
{
if(!strcmp(stutemp->stu_schid,pdata))
{
linkhead=NEW(link);
linkhead->data=mystuinfo->stu_seek;
linkhead->next=NULL;
return linkhead;
}
break;
}
case SEARCH_NAME:
{
if(!strcmp(stutemp->stu_name,pdata))
{
linktemp=NEW(link);
linktemp->data=mystuinfo->stu_seek;
linktemp->next=linkhead;
linkhead=linktemp;
}
break;
}
default:return NULL;
}
}
return linkhead;
}
/*
本函数将二进制的数据库文件以文本模式重写
使得二进制数据库文件中的内容透明化,同时
便于及时发现数据库中的变量异常
*/
void showfile()
{
FILE *ftest=fopen(INFOPATH,"w+");
if(!ftest)seterr("showfile:ftest null");
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
fprintf(ftest,"fileinfo\t\t:\n");
fprintf(ftest,"stucount\t\t:%d\n",myfileinfo->stucount);
fprintf(ftest,"countmax\t\t:%d\n",myfileinfo->countmax);
fprintf(ftest,"subcount\t\t:%d\n",myfileinfo->subcount);
fprintf(ftest,"spacecount\t\t:%d\n",myfileinfo->spacecount);
int i=0,j=0;
fprintf(ftest,"\nseek:\n");
for(i=0;i<MAXSPACECOUNT;i++)
{
fprintf(ftest,"%ld\t",myfileinfo->seek[i]);j++;
if(j>=10){fprintf(ftest,"\n");j=0;}
}
fprintf(ftest,"\n\nsubinfo:\n");
psubinfo subtemp=myfileinfo->sub;
fprintf(ftest,"\tflag\t\tsub_id\t\tsub_term\t\tsub_rate\t\tsub_name\n");
for(i=0;i<MAXSUBCOUNT;i++,subtemp++)
{
fprintf(ftest,"\t%d\t\t",subtemp->flag);
fprintf(ftest,"%d\t\t",subtemp->sub_id);
fprintf(ftest,"%d\t\t\t",subtemp->sub_term);
fprintf(ftest,"%3.1f\t\t\t",subtemp->sub_rate);
fprintf(ftest,"%s\n",subtemp->sub_name);
}
fprintf(ftest,"\nstudent info :\n\n");
fseek(fp,0L,SEEK_END);
long size=ftell(fp),seek=DATASEEK;
int allcount=(size-FILEINFOSIZE)/DATATRANS;
if(!mystuinfo)mystuinfo=NEW(stuinfo);
psubmark marktemp=NULL;
pmystu stutemp=NULL;
for(i=0;i<allcount;i++,seek+=DATATRANS)
{
memset(mystuinfo,0,STUINFOSIZE);
fcntl(seek,READ,mystuinfo,STUINFOSIZE);
stutemp=&mystuinfo->stu_privacy;
fprintf(ftest,"flag\t\t:\t%d\n",mystuinfo->flag);
fprintf(ftest,"stu_sysid\t:\t%d\n",mystuinfo->stu_sysid);
fprintf(ftest,"stu_name\t:\t%s\n",stutemp->stu_name);
fprintf(ftest,"stu_schid\t:\t%s\n",stutemp->stu_schid);
if(stutemp->stu_sex)fprintf(ftest,"stu_sex\t\t:\t女\n");
else fprintf(ftest,"stu_sex\t\t:\t男\n");
fprintf(ftest,"stu_major\t:\t%s\n",stutemp->stu_major);
fprintf(ftest,"stu_seek\t:\t%ld\n",mystuinfo->stu_seek);
fprintf(ftest,"stu_markcount\t:\t%d\n",mystuinfo->stu_markcount);
fprintf(ftest,"stu_avemark\t:\t%4.1f\n",mystuinfo->stu_avemark);
fprintf(ftest,"stumark:\n");
marktemp=mystuinfo->stu_mark;
fprintf(ftest,"\t\tflag\t\t\t\t\tsub_id\t\t\t\t\tsub_mark\n");
for(j=0;j<MAXSUBCOUNT;j++)
{
fprintf(ftest,"\t\t%d\t\t\t",marktemp[j].flag);
fprintf(ftest,"\t\t%d\t\t\t",marktemp[j].sub_id);
fprintf(ftest,"\t\t%4.1f\n",marktemp[j].sub_mark);
}
}
fclose(ftest);
}
//本函数用于单链表排序
plink sortlink(plink linkhead,int sorttype)
{
if(!linkhead||!linkhead->next)return linkhead;
plink q=linkhead,s,temp=NEW(link);
temp->next=q ;int flag1,flag2,flag;
flag=sorttype-SORT_INCLINE;
while(linkhead&&linkhead->next)
{
while(temp-linkhead)
{
s=linkhead->next ;
if(!s)break ;
flag1=s->mark<q->mark;
flag2=s->mark<temp->next->mark;
if(flag?!flag1:flag1)
{
linkhead->next=s->next ;
s->next=q ;
q=s ;
temp=q ;
}
else if(flag?!flag2:flag2)
{
linkhead->next=s->next ;
s->next=temp->next ;
temp->next=s ;
temp=q ;
}
else temp=temp->next ;
}
linkhead=linkhead->next ;
temp=q ;
}
return q ;
}
//建立单链表
plink makelink(plink linkhead,double mark,long seek)
{
plink linktemp=NEW(link);
linktemp->mark=mark;
linktemp->next=linkhead;
linktemp->data=seek;
linkhead=linktemp;
return linkhead;
}
//本函数用于将每个学生某科的成绩建立单链表
plink marklink(int markid)
{
if(markid<-1||markid>MAXSUBCOUNT)return NULL;
if(!markid)return NULL;
plink linkhead=NULL;
if(!myfileinfo)
{
myfileinfo=NEW(fileinfo);
fcntl(0,READ,myfileinfo,FILEINFOSIZE);
}
if(!mystuinfo)mystuinfo=NEW(stuinfo);
int stucount=myfileinfo->stucount,i;
long seek=DATASEEK;
psubmark marktemp=mystuinfo->stu_mark;
for(i=0;i<stucount;i++,seek+=DATATRANS)
{
memset(mystuinfo,0,STUINFOSIZE);
fcntl(seek,READ,mystuinfo,STUINFOSIZE);
if(!mystuinfo->flag){i--;continue;}
if(!mystuinfo->stu_markcount)continue;
if(markid==-1)
linkhead=makelink(linkhead,mystuinfo->stu_avemark,mystuinfo->stu_seek);
else if(marktemp[markid-1].flag)
linkhead=makelink(linkhead,marktemp[markid-1].sub_mark,mystuinfo->stu_seek);
}
return linkhead;
}
//释放整条链表的空间
void freelink(plink linkhead)
{
if(!linkhead)return;
plink linktemp=linkhead;
while(linkhead)
{
linktemp=linkhead->next;
free(linkhead);
linkhead=linktemp;
}
}
//本函数用于测试链表中的变量是否异常之用
void showlink(plink linkhead)
{
int j=1;
while(linkhead&&j)
{
printf("mark:%5.1f\t\t",linkhead->mark);
printf("seek:%ld\t\t",linkhead->data);
printf("next:%p\t\n",linkhead->next);
linkhead=linkhead->next;
printf("input:");
scanf("%d",&j);
}
}
//本函数用于测试该类型的结构体中变量值是否异常之用
void showsubmark(psubmark marktemp)
{
printf("flag:%d\t",marktemp->flag);
printf("subid:%d\t",marktemp->sub_id);
printf("submark:%5.1f\n",marktemp->sub_mark);
}
//本函数用于测试该类型的结构体中变量值是否异常之用
void showsubinfo(psubinfo subtemp)
{
printf("\nflag:%d\t",subtemp->flag);
printf("sub_id:%d\t",subtemp->sub_id);
printf("subterm:%d\n",subtemp->sub_term);
printf("rate:%3.1f\t",subtemp->sub_rate);
printf("name:%s\n",subtemp->sub_name);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -