电子地图管理系统

来源:互联网 发布:Mac官网源码 编辑:程序博客网 时间:2024/06/07 18:34
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>/*函数声明部分*/void ma_interf();int ReadFile();void ReadData(FILE *p);void WriteResult (int b[] , int j);void Search();/*宏定义*/#define MCGETCHAR(data)  (*((char *)(data)))#define MCGETSHORT(data)  ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff )))#define MCGETLONG(data)  ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )#define MCGET3BN(data)  ( ( ((unsigned long)MCGETCHAR((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+1))&0x0000ffff ) )#define Length 655350 int nsizecount = 2 ;/*定义结构体类型及变量*/struct  RoadRecord{short ussize;long  ullinkId;short usroadnamesize;int   usdispclass;int   usbrunch;int   usroadnameflag;char  roadname[20];};struct tagMap_t{char sign_one[2];char linkid[14];char flag[7];char brunch[9];char dispclass[13];char Roadname[30];char sign_two[2];}*s , *ss;int mark_1=0,mark_2=0;    //标记程序是否运行读取文件和排序操作void SortData(tagMap_t s[]);void Update (tagMap_t s[]); struct dataOut{   long linkId;int  dispclass;int  brunch;int  roadnameflag;};struct RoadRecord road[Length];struct dataOut data[Length]; /*存储道路信息的数组*/      /***************************************************************************************Functionname:ReadFile  **Function Description:读取二进制文件,并将其解析在文本文档里  **Date:2012/6/20      * **************************************************************************************/int   ReadFile() { int  m;char aclinkId[4] ;/*从二进制文件中读取道路编号*/    char acroadnamesize[2] ;    /*从二进制文件中读取道路名称数据长度*/    char acNodeInfo[4];unsigned short ustotalsize;    unsigned long  ullinkId;    unsigned short usroadnamesize;char actotalsize[2] ;   /*从二进制文件中读取道路信息的总体数据长度 */FILE *pfp = fopen( "e:\\电子地图管理系统.dat " ,  "rb+"); FILE *pf2 = fopen( "e:\\解析文件.txt " ,  "w+"); if(pfp == NULL){printf("can not open the 电子地图管理系统.dat file or there is no the file!\n");return 0;}if(pf2 == NULL){printf("can not open the 解析文件.txt file or there is no the file\n");return 0;}printf("\n\n\t\t\t\t文件读取中.....\n");while(fread(actotalsize , sizeof(actotalsize) , 1 , pfp) == 1)    {        fread( aclinkId , sizeof(aclinkId) , 1 , pfp ) ;/*读取占用4字节的linkId字符*/      fread( acroadnamesize , sizeof(acroadnamesize) , 1 , pfp ) ;/*读取占用2字节的roadnamesize字符串*/ fread( acNodeInfo , sizeof(acNodeInfo) , 1 , pfp ) ;   ustotalsize = MCGETSHORT(actotalsize) ;/*调用宏函数 , 将字符串信息转化为数值类型*/ullinkId = MCGETLONG(aclinkId) ;usroadnamesize = MCGETSHORT(acroadnamesize) ;/*赋值 :将数值信息传到结构体中*/ road[nsizecount].ussize = ustotalsize ;road[nsizecount].ullinkId = ullinkId ;road[nsizecount].usroadnamesize= usroadnamesize ;m=(int)acNodeInfo[3]&255;road[nsizecount].usdispclass=m&15;road[nsizecount].usbrunch=(m&112)/16;road[nsizecount].usroadnameflag=(m&128)/128;data[nsizecount].dispclass= road[nsizecount].usdispclass;data[nsizecount].brunch=road[nsizecount].usbrunch;data[nsizecount].roadnameflag=road[nsizecount].usroadnameflag;data[nsizecount].linkId= ullinkId;fread(road[nsizecount].roadname , sizeof(char) , ustotalsize - 12 , pfp ) ;/*从文件中读取道路名称*/fprintf(pf2 , "#\t");fprintf(pf2 , "LinkID=");fprintf(pf2 , "%d\t" , data[nsizecount].linkId);fprintf(pf2 , "flag=");fprintf(pf2 , "%d\t" , data[nsizecount].roadnameflag);fprintf(pf2 , "brunch=");fprintf(pf2 , "%d\t" , data[nsizecount].brunch);fprintf(pf2 , "dispclass=");fprintf(pf2 , "%d\t" , data[nsizecount].dispclass);fprintf(pf2 , "Roadname=1=");fprintf(pf2 , "%s\t" , road[nsizecount].roadname+4);fprintf(pf2 , "#");fprintf(pf2 , " \n");nsizecount++;}fclose(pfp); fclose(pf2); printf("\n\t\t\t\t 文件读取成功\n");return  0; }/***************************************************************************************Functionname:Search  **Function Description:检索信息部分,可按不同的类型进行检索       **Date:2012/6/20      * **************************************************************************************/void Search(){int  select , i=0 , j=0 , *b , c=0 , f;  //select 标记选择需要运行的分支  i 循环控制  j标记检索到信息的条数  //b 数组指针 用来存放检索到的信息的下标 c 用来存放数组b的下标  f 标记数组b的值char sss[20];printf("\n\n\t请输入检索方式:\n\n\t\t1:指定linkID 检索\n\n\t\t2:指定交叉link列表示class番号 检索\n\n\t\t3:指定查找岔路数 检索\n\n\t\t4:指定道路名称 检索\n\n\t\t0:返回\n\n\t\t请选择:");scanf("%d" , &select);system("cls");printf("\n\n*****--当检索到信息条数超过5条时 , 会把检索到的信息存放在searchresult文件中--*****\n\n");printf("\n********--当检索到信息条数未超过5条时 , 会把检索到的信息直接显示在屏幕上--********\n\n\n");if(select == 1){char ss_1[14]="LinkID=";printf("\t请输入link的ID:");scanf("%s" , sss);system("cls");strcat(ss_1 , sss);//连接字符串 for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].linkid) == 0)    //比较字符串是否一致{printf("\n\n  %s %s %s %s %s %s %s\n\n\n" , s[i].sign_one , ss[i].linkid , ss[i].flag , ss[i].brunch , \ss[i].dispclass , ss[i].Roadname , s[i].sign_two);j++;}}if(j == 0){printf("\n\n\t\t\t\t没有匹配结果\n\n\t\t\t    请重新选择检索方式\n");Search();}}else if(select == 2){char ss_1[14]="dispclass=";printf("\t请输入交叉link列表示class番号:");scanf("%s" , sss);system("cls");strcat(ss_1 , sss);//连接字符串for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].dispclass) == 0)//比较字符串是否一致{j++;}}b=(int *)malloc(sizeof(int)*j);//动态申请数组b的存储空间for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].dispclass) == 0)//比较字符串是否一致{b[c]=i;c++;}}if(j == 0){printf("\n\n\t\t\t\t没有匹配结果\n\n\t\t\t    请重新选择检索方式\n");Search();}else if(j>5){WriteResult(b  ,  j);}else if (j<=5)//判断检索到得条数是否超过5条{printf("\n\n");for(i=0; i<j; i++){f=b[i];printf("  %s %s %s %s %s %s %s\n" , s[f].sign_one , ss[f].linkid , ss[f].flag , ss[f].brunch , \ss[f].dispclass , ss[f].Roadname , s[f].sign_two);}printf("\n\n");}free(b);}else if(select == 3){char ss_1[14]="brunch=";printf("\t请输入岔路数:");scanf("%s" , sss);system("cls");strcat(ss_1 , sss);//连接字符串for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].brunch) == 0)//比较字符串是否一致{j++;}}b=(int *)malloc(sizeof(int)*j);//动态申请数组b的存储空间for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].brunch) == 0)//比较字符串是否一致{b[c]=i;c++;}}if(j == 0){printf("\n\n\t\t\t\t没有匹配结果\n\n\t\t\t    请重新选择检索方式\n");Search();}else if(j>5){WriteResult(b  ,  j);}else if (j<=5)//判断检索到得条数是否超过5条{printf("\n\n");for(i=0; i<j; i++){f=b[i];printf("  %s %s %s %s %s %s %s\n" , s[f].sign_one , ss[f].linkid , ss[f].flag , ss[f].brunch , \ss[f].dispclass , ss[f].Roadname , s[f].sign_two);}printf("\n\n");}free(b);}else if(select == 4){char ss_1[14]="Roadname=1=";printf("\t请输入道路名称:");scanf("%s" , sss);system("cls");strcat(ss_1 , sss);//连接字符串for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].Roadname) == 0)//比较字符串是否一致{j++;}}b=(int *)malloc(sizeof(int)*j);//动态申请数组b的存储空间for(i=0; i<(nsizecount-2); i++){if(strcmp(ss_1 , ss[i].Roadname) == 0)//比较字符串是否一致{b[c]=i;c++;}}if(j == 0){printf("\n\n\t\t\t\t没有匹配结果\n\n\t\t\t    请重新选择检索方式\n");Search();}else if(j>5)//判断检索到得条数是否超过5条{WriteResult(b , j);}else if (j<=5){printf("\n\n");for(i=0; i<j; i++){f=b[i];printf("  %s %s %s %s %s %s %s\n" , s[f].sign_one , ss[f].linkid , ss[f].flag , ss[f].brunch , \ss[f].dispclass , ss[f].Roadname , s[f].sign_two);}printf("\n\n");}free(b);}else if(select == 0){system("cls");ma_interf();}else// 输入不在0到4之间给出提示信息 重新返回检索函数{system("cls");printf("\n\n\t\t输入信息错误,请重新选择检索方式\n\n");Search();}ma_interf();// 执行结束 返回主界面}/***************************************************************************************Functionname: WriteResult  **Function Description:检索信息,当超过5条时,就将信息写入一个文档中  **Date:2012/6/21      * **************************************************************************************/void WriteResult (int b[] , int j){FILE *qq;if((qq=fopen("e:\\searchresult.txt" , "w")) == NULL)  //判断文件是否创建成功{printf("创建文件失败\n");exit(0);}int i=0 , f;//  i 为循环控制变量  f 记录传入数组在不同的i下 b[i]  的值printf("\n\n\t\t\t检索到的信息超过--5--条\n\n\n\t\t检索到的信息写入searchresult文件中……\n");for(i=0; i<j; i++){f=b[i];fprintf(qq , "#\t");fprintf(qq , "%s\t" , ss[f].linkid);// 检索到的道路信息写入文件中fprintf(qq , "%s\t" , ss[f].flag);// 检索到的道路信息写入文件中fprintf(qq , "%s\t" , ss[f].brunch);// 检索到的道路信息写入文件中fprintf(qq , "%s\t" , ss[f].dispclass);// 检索到的道路信息写入文件中fprintf(qq , "%s\t" , ss[f].Roadname);// 检索到的道路信息写入文件中fprintf(qq , "#");fprintf(qq , "\n");}fclose(qq);//关闭指针qqprintf("\n\n\t\t检索到的信息写入searchresult文件中成功\n\n\n");}void ma_interf(){int select;//select 控制在主界面是选择需要执行的函数FILE *p;//创建解析文件的文件指针printf("/********************************--Welcome--**********************************/\n");printf("/***\t\t\t\t\t\t\t\t\t   ***/\n");printf("/***\t\t\t电子地图信息统计系统\t\t\t\t   ***/\n");printf("/***\t\t\t\t\t\t\t\t\t   ***/\n");printf("/*******************************************************************************/\n\n");printf("请选择服务的种类:\n");printf("\t1:读取文件(e:电子地图管理系统GTBL.dat)\n\t2:排序并输出结果\n\t3:检索\n\t4:更新\n\t0:退出\n\t请选择:");scanf("%d" , &select);system("cls");switch(select){case 1 :ReadFile();s=(struct tagMap_t *)malloc(sizeof(struct tagMap_t)*(nsizecount-2));//动态申请结构体s的内存空间ss=(struct tagMap_t *)malloc(sizeof(struct tagMap_t)*(nsizecount-2));//动态申请结构体ss的内存空间p=fopen("e:\\解析文件.txt" , "r");mark_1++;//标记是否执行读取文件ReadData(p);break;case 2 :if(mark_1!=1){printf("\n\n\t请在进行排序前先选择-1-进行读取文件,否则无数据进行排序\n\n");ma_interf();}else if(mark_1==1){mark_2++;//标记是否执行排序操作SortData(s);}break;case 3 :if(mark_1==0||mark_2==0)//判断是否执行 读取文件  和排序道路信息{printf("\n\n\t\t请在进行-检索-前先选择-1--2-进行读取文件和排序操作\n\n");printf("\t\t     否则无数据进行检索或检索到的数据未排序\n\n");ma_interf();}else{Search();}break;case 4 :if(mark_1==0||mark_2==0)//判断是否执行 读取文件  和排序道路信息{printf("\n\n\t\t请在进行-更新-前先选择-1--2-进行读取文件和排序操作\n\n");printf("\t\t   否则无数据进行更新或更新到得数据未排序\n\n");ma_interf();}else{Update(s);break;}case 0 :if(mark_1!=0)//判断是否打开申请s 和ss 的空间{free(s);//释放s内存free(ss);//释放ss内存}exit(0);break;default:system("cls"); printf("\n\n\n\t\t\t输入信息出错,请重新选择服务种类:\n\n\n\n");ma_interf();//执行结束 返回主界面}}/***************************************************************************************Functionname:Judge           **Function Description:判断解析出来的文件是否存在  **Date:2012/6/20      * **************************************************************************************/int Judge(){FILE *pp;if((pp=fopen("e:\\电子地图管理系统.dat" , "rb")) == NULL)    //打开文件 并返回pp文件指针 判断文件是否存在{system("cls");printf("\n\n\t\t\t\tthe file not exist!\n\n\t\t\t\t  请重新选择服务:\n\n");printf("\n\t请将需要解析的--电子地图管理系统.dat--放入--e:\\根目录下--中\n\n");return 0;}else{return 1;}}/***************************************************************************************Functionname:ReadData  **Function Description:将文件信息读取到内存中  **Date:2012/6/21      * **************************************************************************************/ void ReadData(FILE *p){if((Judge()) == 1)//判断文件Judge 函数的返回值{int i=0;//i  为循环控制变量printf("\n\t\t\t文件信息--------写入内存中……\n");for(i=0;i<(nsizecount-2);i++){fscanf(p , "%s" , s[i].sign_one);//道路信息放入内存中fscanf(p , "%s" , s[i].linkid);//道路信息放入内存中fscanf(p , "%s" , s[i].flag);//道路信息放入内存中fscanf(p , "%s" , s[i].brunch);//道路信息放入内存中fscanf(p , "%s" , s[i].dispclass);//道路信息放入内存中fscanf(p , "%s" , s[i].Roadname);//道路信息放入内存中fscanf(p , "%s" , s[i].sign_two);//道路信息放入内存中}if(s[1].sign_one!="")//判断文件信息是否写入成功printf("\n\t\t\t  文件信息-------写入内存成功\n\n");ma_interf();//返回主界面}else{ma_interf();//返回主界面}}/***************************************************************************************Functionname: SortData    **Function Description:对读取出来的文件信息进行排序并将排序结果显示在屏幕上  **Date:2012/6/21      * **************************************************************************************/void SortData(tagMap_t s[]){int  i=0 , k=0 , j=0 , m=0 , n=7;  //i k 为循环控制变量  n 记录linkid的长度  m 标记成功排序的个数  char temp[50];printf("\n\n\t\t\t排序中…………请等待!…………\n\n\t\t排序完成后将自动按LinkID编号由小到大显示所有道路信息\n\n");for(n=8; n<13; n++){for(i=0; i<(nsizecount-2); i++){if((int)strlen(s[i].linkid) == n)// 判断linkid的长度是否为n{k=i;//记录 Linkid长度为n时 数组s 的下标ij=i;//记录 Linkid长度为n时 数组s 的下标ifor(k=k+1; k<(nsizecount-2); k++)//继续进行下一次循环{if((int)strlen(s[k].linkid) == n)// 判断linkid的长度是否为n{if(strcmp(s[i].linkid , s[k].linkid)>0)//比较linkid的长度同为n时它们的大小{i=k;//记录下当前检索到最小linkid的s数组的下标}}}strcpy(ss[m].linkid , s[i].linkid);//此时最小linkid 把数组s的信息存放到ss数组中strcpy(ss[m].flag , s[i].flag);//此时最小linkid 把数组s的信息存放到ss数组中strcpy(ss[m].brunch , s[i].brunch);//此时最小linkid 把数组s的信息存放到ss数组中strcpy(ss[m].dispclass , s[i].dispclass);//此时最小linkid 把数组s的信息存放到ss数组中strcpy(ss[m].Roadname , s[i].Roadname);//此时最小linkid 把数组s的信息存放到ss数组中strcpy(temp , s[j].linkid);//交换s[i]和s[j]中linkid的信息strcpy(s[j].linkid , s[i].linkid);strcpy(s[i].linkid , temp);strcpy(temp , s[j].flag);//交换s[i]和s[j]中flag的信息strcpy(s[j].flag , s[i].flag);strcpy(s[i].flag , temp);strcpy(temp , s[j].brunch);//交换s[i]和s[j]中brunch的信息strcpy(s[j].brunch , s[i].brunch);strcpy(s[i].brunch , temp);strcpy(temp , s[j].dispclass);//交换s[i]和s[j]中dispclass的信息strcpy(s[j].dispclass , s[i].dispclass);strcpy(s[i].dispclass , temp);strcpy(temp , s[j].Roadname);//交换s[i]和s[j]中Roadname的信息strcpy(s[j].Roadname , s[i].Roadname);strcpy(s[i].Roadname , temp);m++;//记录已排序成功道路信息的个数i=j;if(m%830 == 0)  //排序进度提示符 . 的输出控制    830 时刚好输出 1 行 . 且进度刚好100%{ printf(".");}if(m%100==0)// 控制百分数输出{if(((float)m/(nsizecount-2))*100<10){printf("%.1f%%%\b\b\b\b" , ((float)m/(nsizecount-2))*100);}else if (((float)m/(nsizecount-2))*100>=10){printf("%.1f%%%\b\b\b\b\b" , ((float)m/(nsizecount-2))*100);}}}}}system("cls");for(i=0;i<m;i++){printf("    %s   %s  %s  %s  %s  \n" , ss[i].linkid , ss[i].flag , ss[i].brunch , ss[i].dispclass , ss[i].Roadname);}printf("\n\n\t\t排序成功-----按LinkID编号由小到大显示完成\n\n");ma_interf();//排序完成  返回主界面}/***************************************************************************************Functionname:Update          **Function Description:对数据进行更新,并将更新后的结果存入新的文件中  **Date:2012/6/22      * **************************************************************************************/void Update (tagMap_t s[]){FILE *pp;   //定义文件指针 用来创建新的newfile 文件char pc[60];int i=0;//循环控制变量if((pp=fopen("e:\\newfile.txt " , "w")) == NULL)//判断穿件文件是否成功{printf("更新文件创建失败……");exit(0);}for(i=0; i<(nsizecount-2); i++){fprintf(pp , "#\t");fprintf(pp , "%s\t" , ss[i].linkid);//文件信息写入newfile 文件中fprintf(pp , "%s\t" , ss[i].flag);//文件信息写入newfile 文件中fprintf(pp , "%s\t" , ss[i].brunch);//文件信息写入newfile 文件中fprintf(pp , "%s\t" , ss[i].dispclass);//文件信息写入newfile 文件中fprintf(pp , "%s\t" , ss[i].Roadname);//文件信息写入newfile 文件中fprintf(pp , "#");fprintf(pp , "\n");}fclose(pp);//关闭文件指针ppif((pp=fopen("e:\\newfile.txt" , "r")) == NULL)//打开文件 newfile  为更新文件提供数据{printf("the newfile open fail\n");exit(0);}FILE *ppp;//文件指针  用来创建update文件if((ppp=fopen("e:\\update.dat" , "wb")) == NULL)//判断文件创建是否成功{printf("更新文件创建失败\n");exit(0);}system("cls");printf("\n\n\t\t\t\t文件更新中……\n");//给出提示信息for(i=0; i<(nsizecount-2); i++){fread(pc , 56 , 1 , pp);//newfile 文件信息写入 pc 数组中fwrite(pc , 56 , 1 , ppp);//数组pc的信息写入update二进制文件中}printf("\n\n\t\t\t\t文件更新成功\n\n\n\t\t\t更新文件存放在update.dat文件中\n\n\n");ma_interf();//返回主界面}void main(){ma_interf();//进入主界面}

0 0