#include "macro.h"
extern UINT4 GetNumber();
extern UINT4 GetChoice1(char (*notice)[20], UINT1 n);
extern UINT4 GetChoice2(char (*notice)[20], UINT1 n);
extern void Sort(RoadInfor numbers[],int num);
extern void Print(RoadInfor proadInfor[],UINT4 start,UINT4 num,char stytle[]);
extern int CheckLinkID(RoadInfor roadInfor[],UINT4 first,UINT4 last,UINT4 num,UINT4 linkID);
extern void CheckDispClass(RoadInfor roadInfor[],UINT4 num,UINT4 dispClass);
extern void CheckBrunch(RoadInfor roadInfor[],UINT4 num,UINT4 brunch);
extern void CheckRoadName(RoadInfor roadInfor[], UINT4 num, char roadName[40]);
extern void UpdateData(RoadInfor *proadInfor,UINT4 start, UINT4 num);
extern void Show(RoadInfor *proadInfor);
void main()
{
FILE *fp;
RoadInfor roadInfor;//结构体对象
RoadInfor *proadInfor;//结构体指针
char (*proadName)[60];//道路名数组指针
UINT4 brunch = 0;//用于检索的brunch岔路数
UINT4 dispClass = 0;//用于检索的dispClass番号
char roadName[60] = {0};//用于检索的roadname道路名
UINT2 totalSize = 0;//存放记录总长度
UINT2 roadNameSize = 0;//存放道路名称长度
UINT4 linkID = 0;//存放转换的linkID及检索linkID
UINT4 counter = 0;//计数器,存放文件指针每次相对于起始位置的偏移量
UINT4 count = 0;//存放文件中的记录结尾相对于起始位置的偏移量
UINT4 roadNameNum = 0;//存放道路名称个数
UINT4 num = 0;//存放总记录个数
UINT4 i = 0,j = 0;//计数器
UINT4 choice1 = 0,choice2 = 0;//用户选择数
UINT1 flag1 = 1,flag2 = 1;
char notice1[][40] = {"1.排序输出/n","2.检索/n","3.更新/n","0.退出/n"};
char notice2[][40] = {"1.指定linkID检索/n","2.指定交叉Link列表示Class番号 检索/n","3.指定查找岔路数 检索/n","4.指定道路名称 检索/n","0.返回/n"};
if(NULL == (fp = fopen("GTBL.dat","r")))
{
printf("打开文件失败!");
exit(1);
}
//获取文件中的记录数量
fread(&roadInfor,sizeof(RoadInfor),1,fp);
totalSize = MC_GET_SHORT(roadInfor.recordTotalSize);//计算该记录总长度
roadNameSize = MC_GET_SHORT(roadInfor.roadNameSize);//获取道路名字的字节长度
counter = totalSize + counter;//计算从文件起始地址的偏移量
fseek(fp,counter,SEEK_SET);//定位到下一条记录,移动记录Size个字节
while(totalSize > 0)//当该记录长度和编号大于0时,说明该记录有效
{
fread(&roadInfor,sizeof(RoadInfor),1,fp);//读取一个结构体长度的数据
totalSize = MC_GET_SHORT(&roadInfor.recordTotalSize);//计算该记录总长度
roadNameSize = MC_GET_SHORT(&roadInfor.roadNameSize);//获取道路名字的字节长度
counter = totalSize + counter;//计算从文件起始地址的偏移量
fseek(fp,counter,SEEK_SET);//定位到下一条记录,移动记录Size个字节
num ++;//总记录得数量
if(roadNameSize<totalSize)//数据中公路名字的长度小于该记录总长度,说明该记录存有公路的名称
{
roadNameNum++;//有名称的道路的数量
}
}
count=counter;//获取文件中的记录结尾相对于起始位置的偏移量
if(NULL==(proadInfor=(RoadInfor*)malloc(num*sizeof(RoadInfor))))//申请存放所有记录的结构体类型的内存
{
printf("申请内存失败!");
exit(1);
}
if(NULL==(proadName = (char**)malloc((roadNameNum))))//申请存放所有有名称的道路的char[60]类型内存
{
printf("申请内存失败!");
exit(1);
}
counter=0;//计数器置0
printf("总记录数为:%d/n",num);
fseek(fp,counter,SEEK_SET);//counter已置0,定位到文件头
while(i < num && feof(fp) == 0)
{
fread(&proadInfor[i],sizeof(RoadInfor),1,fp);//读取一个结构体长度的数据
totalSize = MC_GET_SHORT(proadInfor[i].recordTotalSize);//计算该记录总长度
linkID = MC_GET_LONG(proadInfor[i].linkID);//计算linkID的值
roadNameSize = MC_GET_SHORT(proadInfor[i].roadNameSize);//获取道路名字的字节长度
fseek(fp,-N,SEEK_CUR);//将结构体中指针的4个字节长度退回,定位到道路名称的起始读取地址
if(proadInfor[i].nodeInfor.flag == 0 )//如果道路名称标志flag为0,则说明无道路名称
{
roadNameSize = 0;
proadInfor[i].roadName = NULL;
}
else
{
fscanf(fp,"%s",proadName[j]);//用proadName[j]获取道路名称,proadName为roadNameNum个大小是char[60]的一维指针
proadInfor[i].roadName = proadName[j];//道路名称首地址赋值给结构体相应的指针
j++;
}
counter = totalSize + counter;//计算从文件起始地址的偏移量
fseek(fp,counter,SEEK_SET);//定位到下一条记录,移动记录Size个字节
i++;
}
num--;
fclose(fp);
while(flag1 > 0)
{
choice1 = GetChoice1(notice1,4);
switch(choice1)
{
case 1:
Sort(proadInfor,num);//排序
Print(proadInfor,0,num,"ab+");//写入新的二进制文件
break;
case 2:
while(flag2 > 0)
{
choice2 = GetChoice2(notice2,5);
switch(choice2)
{
case 1:
Sort(proadInfor,num);
printf("请输入要检索的linkID(只能为数字):/n");//指定linkID检索
linkID = GetNumber();
CheckLinkID(proadInfor,0,num,num,linkID);
break;
case 2:
printf("请输入要查找的Class番号(只能为数字):/n"); //指定交叉Link列表示Class番号 检索
dispClass = GetNumber();
CheckDispClass(proadInfor,num,dispClass);
break;
case 3:
printf("请输入要查找的岔路数(只能为数字):/n");//指定查找岔路数 检索
brunch = GetNumber();
CheckBrunch(proadInfor,num,brunch);
break;
case 4:
printf("请输入要检索的道路名称:/n");//指定道路名称 检索
fgets(roadName,40,stdin);
CheckRoadName(proadInfor,num,roadName);
fflush(stdin);
break;
default:
flag2 = 0;
}
}
flag2 = 1;
break;
case 3:
Sort(proadInfor,num);
UpdateData(proadInfor,0,num);
break;
default:
flag1 = 0;
}
}
}