电子地图管理系统
2015-07-09 21:47
363 查看
#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); //关闭指针qq printf("\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 的下标i j=i; //记录 Linkid长度为n时 数组s 的下标i for(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); //关闭文件指针pp if((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(); //进入主界面 }
相关文章推荐
- qt图像类
- Viemu for 2008 如何高亮选中的单词?
- C/C++的数值常数后缀的使用总结
- 一个示例让你明白适配器模式
- 史上最全的程序员求职渠道总结
- [Linux]VM ubuntu-1204-64bit update后分辨率调高会显示异常
- 设计模式_面向对象设计原则简述
- leetcode-112-Path Sum
- datetime方法
- android drag
- ArcEngine:空间索引格网大小无效
- 模式 - KVO
- 【数字图像处理之三】拉普拉斯边缘检测算法
- 匹配不包含指定中文字符的行
- 时间日期设置--ctime头文件
- 第十二篇 SQL Server代理多服务器管理
- 苹果APNs机制
- velocity初步认识
- Windows下编译fast rcnn
- gdb多线程调试