好友
阅读权限 10
听众
最后登录 1970-1-1
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MCGETCHAR(date)(*((char *)(date)))
#define MCGETSHORT(date)((unsigned short)((((unsigned short)(*((char*)(date))))<<8|(((unsigned short)(*((char*)(date)+1)))&0x00ff))
#define MCGETLONG(date)((((unsigned long)MCGETSHORT((date)))<<16|(((unsigned long)MCGETSHORT((char*)(date)+2))&0x0000ffff))
#define MCGET3BN(date)((unsigned short)((((unsigned long)MCGETCHAR((date)))<<16|(((unsigned long)MCGETSHORT((char*)(date+1))&0x0000ffff))
#define Length 65535
int Sizecount=2;
int Mark_1=0,Mark_2=0;
int ReadFile();//读取文件
void Qsort(int i,int r);//排序
int Binsearch(int s,int t,int key);//二分查找
int Search();//检索
void Update();//更新
struct RoadRecord
{
short ussize;
long ulLinkID;
short usRoadnamesize;
int usDispclass;
int usBrunch;
int usRoadnameflag;
char Roadname[20];
};
struct RoadRecord road[Length];
struct Datestore//定义结构体存储数据
{
int n;
char Totalsize[4];
char LinkID_1[5];
char Roadnamesize[2];
char Road_flag[2];
char Roadname[20];
};
static struct Datestore Ds[Length];
struct dateout
{
long LinkID;
int Dispclass;
int Brunch;
int Roadnameflag;
char Roadname[20];
};
struct dateout date[Length];
int ReadFile()//模块一读取文件
{
int m;
char filename[50];
unsigned short ustotalsize;
unsigned long ulLinkID;
unsigned short usRoadnamesize;
FILE*fp_1=fopen("D:\\GTBL.dat","rb+");
FILE*fp_2=fopen("D:\\Newout.txt","w+");
if(fp_1==NULL)//文件不存在手动输入文件路径
{
printf("\n\t 无法打开文件“GTBL.dat”或文件不在D盘根目录下\n\n请手动输入文件路径(路径中请勿有中文):");
return 0;
}
else
{
printf("\n\t文件打开成功!\n\t");
}
if(fp_2==NULL)
{
printf("\n\t无法打开文件“newout.txt”或文件不存在!\n\t");
return 0;
}
printf("\n\t文件读取中......\n");
while(fread(Ds[Sizecount].Totalsize,2,1,fp_1)==1)
{
fread(Ds[Sizecount].LinkID_1,4,1,fp_1);//读取LinkID字符
fread(Ds[Sizecount].Roadnamesize,2,1,fp_1);//读取Roadnamesize字符串
fread(Ds[Sizecount].Road_flag,4,1,fp_1);
ustotalsize = MCGETSHORT(Ds[Sizecount].Totalsize); //调用宏函数将字符串信息转换为数值类型
ulLinkID = MCGETLONG(Ds[Sizecount].LinkID_1);
usRoadnamesize = MCGETSHORT(Ds[Sizecount].Roadnamesize); //赋值将数值信息传到结构体中
Ds[Sizecount].n=ustotalsize-12;
road[Sizecount].ussize=ustotalsize;
road[Sizecount].ulLinkID=ulLinkID;
road[Sizecount].usRoadnamesize=usRoadnamesize;
m=(int)Ds[Sizecount].Road_flag[3]&255;
road[Sizecount].usDispclass=m&15;
road[Sizecount].usBrunch=(m&112)/16;
road[Sizecount].usRoadnameflag=(m&128)/128;
date[Sizecount].Dispclass=road[Sizecount].usDispclass;
date[Sizecount].Brunch=road[Sizecount].usBrunch;
date[Sizecount].Roadnameflag=road[Sizecount].usRoadnameflag;
date[Sizecount].LinkID=ulLinkID;
fread(Ds[Sizecount].Roadname,sizeof(char),ustotalsize-12,fp_1);//从文件中读取道路名称
strcpy(date[Sizecount].Roadname,Ds[Sizecount].Roadname+4);
fprintf(fp_2,"LinkID=");
fprintf(fp_2,"%d\t",date[Sizecount].LinkID);
fprintf(fp_2,"Flag=");
fprintf(fp_2,"%d\t",date[Sizecount].Roadnameflag);
fprintf(fp_2,"Brunch");
fprintf(fp_2,"%d\t",date[Sizecount].Brunch);
fprintf(fp_2,"Dispclass=");
fprintf(fp_2,"%d\t",date[Sizecount].Dispclass);
fprintf(fp_2,"Roadname=");
fprintf(fp_2,"%s\t",date[Sizecount].Roadname);
fprintf(fp_2,"\n");
Sizecount++;
}
fclose(fp_1);
fclose(fp_2);
printf("\n\t文件读取成功\n\n 生成文件<D:\\Newout.txt\n\n");
return 1;
}
void Qsort(int l,int r)//模块二排序(快速排序)
{
int n=date[l].LinkID,i=l,j=r;
date[Length-2]=date[l];
Ds[Length-2]=Ds[l];
if(l>=r)
{
return;
}
while(i<j)
{
while(i<j && date[j].LinkID>=n)
{
--j;
}
{
date[i]=date[j];
Ds[i]=Ds[j];
}
while(i<j && date[i].LinkID<=n)
{
++j;
}
date[j]=date[i];
Ds[j]=Ds[i];
}
date[i]=date[Length-2];
Ds[i]=Ds[Length-2];
Qsort(l,i-1);
Qsort(i+1,r);
}
int Binsearch(int s,int t,int key)//二分查找
{
int low=s,high=t,mid;
if(s<=t)
{
mid=low+(high-low)/2;
if(date[mid].LinkID==key)
{
return mid;
}
else if(date[mid].LinkID>key)
{
return Binsearch(low,mid-1,key);
}
else
{
return Binsearch(mid+1,high,key);
}
}
return -1;
}
int Search()//模块三检索
{
int sel,i,flag=0,n,key,mid,s=2,t=Sizecount;
char Roadname[20];
FILE*p,*p1,*p2;//分别保存不同的道路检索信息
printf("\n 请输入检索方式: \n\t1: 指定 LinkID 检索\n\t2:指定交叉 Link 列表示 Class番号检索\n\t3: 指定查找岔路数检索\n\t4: 指定道路名称检索\n\t0: 返回\n请选择:");
while((scanf("%d",&sel))!=1)//判断输入的数据是否为数字
{
fflush(stdin);
printf("\n\t输入错误,请重新输入!\n");
printf("\n请输入检索方式:\n\t1:指定Link检索\n\t2:指定交叉Link列表示Class番号检索\n\t3:指定查找岔路数检索\n\t4:指定道路名称检索\n\t0:返回\n请选择:");
}
switch(sel)
{
case 1://LinkID检索
{
printf("请输入LinkID:");
scanf("%d",&n);
key=n;
mid=Binsearch(s,t,key);
if(mid!=-1)
{
printf("\n\t检索到的信息不足5条,信息将显示在屏幕上!\n");
printf("\nLinkID=%d\tRoadnameflag=%d\tBrunch=%d\tDisclass=%d\tRoadname=%s\n\n",date[mid].LinkID,date[mid].Roadnameflag,date[mid].Brunch,date[mid].Dispclass,date[mid].Roadname);
flag++;
}
if(flag==0)
{
printf("\n\t没有匹配结果,请重新选择检索方式!\n\n");
Search();
}
return 0;
break;
}
case 2://指定交叉Link列表示Class番号检索
{
printf("请输入交叉Link列表示Class番号");
scanf("%d",&n);
for(i=2;i<=Sizecount;i++)
{
if(date[i].Dispclass==n)
{
flag++;
}
}
if(flag==0)
{
printf("\n\t没有Class番号为%d的道路\n\n",n);
return 0;
}
if(flag<=5)
{
printf("\n\t检索到的信息不足5条,信息将显示在屏幕上!\n");
for(i=2;i<=Sizecount;i++)
{
if(date[i].Dispclass==n)
{
printf("\nLinkID=%d\tRoadnameflag=%\tBrunch=%d\tDispclass=%d\tRoadname=%s\n",date[i].LinkID,date[i].Roadnameflag,date[i].Brunch,date[i].Dispclass,date[i].Roadname);
}
}
return 0;
}
else
{
printf("\n\t结果大于五条,转存到D:\\岔路口检索结果.TXT\n\n");
p1=fopen("D:\\岔路口检索结果.TXT","w+");
for(i=2;i<Sizecount;i++)
{
if(date[i].Brunch==n)
{
fprintf(p1,"\nLinkID=%d\tRoadnameflag=%d\tBrunch=5d\tDispclass=%d\tRoadname=%s",date[i].LinkID,date[i].Roadnameflag,date[i].Brunch,date[i].Dispclass,date[i].Roadname);
}
}
fclose(p1);
return 0;
}
}
break;
case 4://指定道路名称解锁
{
printf("请输入道路名称");
scanf("%s",&Roadname);
for(i=2;i<Sizecount;i++)
{
if(strcmp(date[i].Roadname,Roadname)==0)
{
flag++;
}
}
if(flag==0)
{
printf("\n\t没有道路名称为“%s”");
return 0;
}
else if(flag<=5)
{
printf("\n\t检索到的信息不足五条,信息将显示在屏幕上!\n");
for(i=2;i<Sizecount;i++)
{
if(strcmp(date[i].Roadname,Roadname)==0)
{
printf("\nLinkID=%d\tRoadnameflag=%\tBrunch=%d\tDispclass=%d\tRoadname=%s\n",date[i].LinkID,date[i].Roadnameflag,date[i].Brunch,date[i].Dispclass,date[i].Roadname);
}
}
return 0;
}
else
{
printf("\n\t结果大于5条,转存到D:\\道路名称检索结果.TXT\n\n");
p2=fopen("D:\\道路名称检索结果.txt","w+");
for(i=2;i<Sizecount;i++)
{
if(strcmp(date[i].Roadname,Roadname)==0)
{
fprintf(p2,"\nLinkID=%d\tRoadnameflag=%d\tBrunch=%d\tDispclass=%d\tRoadname=%s",date[i].LinkID,date[i].Roadnameflag,date[i].Brunch,date[i].Dispclass,date[i].Roadname);
}
}
fclose(p2);
return 0;
}
}
break;
case 0:
{
return 0;
}
break;
default://输入不在0到4之间,重新返回检索函数
{
printf("\n\t输入信息有误请重新选择检索方式!\n\n");
Search();
return 0;
}
}
}
void Update()
{
int a;
remove("D:\\GTBL.dat");
a=rename("D:\\Sort.dat","D:\\GTBL.dat");
if(a!=0)
{
printf("\n\t更新失败,无法找到更新文件或请确认操作权限!\n\n");
return;
}
else
printf("\n\t更新成功!\n\n");
}
void main()
{
int a,n=0,i,Mark_3=0,Mark_4=0;
clock_t start,finish;
double Time;
FILE*p1,*p2;
printf("|********************************--#######********************************|\n");
printf("欢迎使用\n");
printf("电子地图管理系统\n");
printf("2021-4-20\n");
printf("|******************************|");
do
{
printf("请选择服务的类型:");
printf("\n\t1:读取文件\n\t2:排序并输出结果\n\t3:检索\n\t4:更新\n\t0:退出\n请选择:");
while((scanf("%d",&a))!=1)//判断输入的数据是否为数字
{
fflush(stdin);//清理缓存
printf("\n\t输入有误,请重新输入!\n\n");
printf("请选择服务的种类:");
printf("\n\t1:读取文件\n\t2:排序并输出结果\n\t3:检索\n\t4:更新\n\t0:退出\n请选择:");
}
switch(a)
{
case 1:
if(Mark_3==1)
{
printf("\n\t 文件已经读取成功,如需再次读取文件,请关闭本程序重试!\n\n");
}
else if(ReadFile()==1)
{
++Mark_1;
Mark_3=Mark_1;//复制Mark_1的值
}
break;
case 2:
if(Mark_2==1)
{
printf("\n\t排序已经完成,如需再次排序请先关闭本程序重试!\n\n");
}
else if(Mark_1==0)
{
printf("\n\t请在排序前先选择“读取文件”操作!\n\n");
}
else if(Mark_1==1)
{
++Mark_2;
if(date[2].LinkID!=1)//检测文件是否有序
{
start=clock();
Qsort(2,Sizecount-1);
finish=clock();
Time=(double)(finish-start)/CLOCKS_PER_SEC;
printf("\n\t排序成功,用时:%f秒!\n\n 排序后的文本文件<D:\\Qsort.txt>\n\n 排序后的二进制文件<D:\\Qsort.dat>\n\n",Time);
p1=fopen("D:\\Sort.dat","wb+");
p2=fopen("D:\\Sort.txt","w+");
for(i=2;i<Sizecount;i++)
{
fprintf(p2,"%d\t",date[i].LinkID);
fprintf(p2,"%d\t",date[i].Brunch);
fprintf(p2,"%d\t",date[i].Dispclass);
fprintf(p2,"%d\t",date[i].Roadnameflag);
fprintf(p2,"%d\t",date[i].Roadname);
fprintf(p2,"\n");
fwrite(Ds[i].Totalsize,2,1,p1);
fwrite(Ds[i].LinkID_1,4,1,p1);
fwrite(Ds[i].Roadnamesize,2,1,p1);
fwrite(Ds[i].Road_flag,4,1,p1);
fwrite(Ds[i].Roadname,sizeof(char),Ds[i].n,p1);
}
fclose(p1);
fclose(p2);
++Mark_4;
}
else
{
printf("\n\t文件有序,无需重复执行此步骤!\n如需继续请将未更新的“GTBL.dat”文件放入D盘更目录下重试!\n\n 排序后的文本文件<D:\\Qsort.txt>\n\n 排序后的二进制文件<D:\\Qsort.dat>\n\n");
}
}
Mark_1=0;
break;
case 3:
if(Mark_3==0)
{
printf("\n\t请先进行“读取文件”操作!\n\n");
}
else if(Mark_3==1 && Mark_2==0)
{
printf("\n\t请在检索前先进行“排序”操作!\n\n");
}
else
{
Search();
}
break;
case 4:
if(Mark_3==0)
{
printf("\n\t请先进行“读取文件”操作!\n\n");
}
else if(Mark_3==1 && Mark_2==0)
{
printf("\n\t请在检索前先进行“排序”操作!\n\n");
}
else if(Mark_4==1)
{
Update();
++Mark_4;
}
else
{
printf("\n\t更新已完成,无需重复此操作!\n\n");
break;
}
break;
case 0:
n++;
break;
default:
printf("\n\t输入错误,请重新输入!\n\n");
}
}
while(n!=1);
}
vs2019提示的错误