1、目 录一、 设计要求 -3二、 概要设计 -3三、 模块设计 -4四、 详细设计 -7五、 测试分析 -10六、 源程序清单-13七、 用户手册-35八、 总结-361 设计要求1.1 问题描述由若干个城市的信息,存入一个带头节点的单链表。节点中的城市信息包括城市名,城市坐标,城市面积,城市人口等。要求能够利用城市名和位置坐标进行有关的查找,插入,删除,更新等操作。1.2 需求分析(1) 输入数据建立城市链表。(2) 能够根据需求实际需求进行查找(3) 能够插入新的城市信息(4) 能够删除不需要的城市的信息(5) 能够修改链表中每一城市的信息(6) 查看链表中所有的城市信息(7) 能够对用户输
2、入的数据进行保存(8) 能够保留用户用户自定义设置2 概要设计为了实现上述需求可以从一下几个方面着手进行设计。2.1 主菜单设计为了实现城市链表各功能的管理,设计一个包含有多个菜单的主控菜单,相应选项连接系统的各个子功能。为方便用户使用,主菜单运行界面如下.2.2 存储结构设计本系统主要采用链表结构类型来存储数据,其中节点由四个部分组成:城市名称,城市坐标,城市人口和城市面积。2.3 系统功能设计本系统共设计了 9 个主要的子功能,各功能的描叙如下所述:(1) 建立城市链表,可以一次性的输入多条城市的信息,建立城市信息表。该功能用CreateCityInfo ( )函数实现。(2) 浏览城市链
3、表信息,可以查看链表中所有城市的信息。该功能由 PrintAll ( )函数来实现。(3) 查找城市中的信息,可以根据您的个性话需求来进行查找,查找设计了一个子菜单,可以选择查找方式。按名称查找,按坐标查找和查找的一定范围内的城市。菜单设计如下通过调用 SearchInfo()函数实现。(4) 插入功能。每次可以插入一条城市信息,插入完后可以选择继续插入信息来进行多条插入。通过调用 InsertInfo( ) 函数来实现。(5) 城市链表的删除,可以按照提示来删除指定的数据。能够让用户选择通过何中方式来确定要删除的文件,提供按名称和按坐标两种,删除成功后会给出“删除成功的提示” 。通过调用 D
4、elInfo( )函数来实现(6) 城市链表的更新功能。能够让用户选择通过何中方式来确定要修改的文件,提供按名称和按坐标两种方式,定位后用户可以选择修改城市的各个信息。通过调用 UpInfo()函数来实现。(7) 文件的载入和保存。用户可以保存目前建立的城市信息,也可以从以前的文件中载入信息,从而实现数据的长期使用。通过调用 FileHandle( ) 函数来实现。(8) 设置。用户可以通过设置来改变文字大小,文字颜色,和界面背景颜色。通过调用UserSetting( )函数来实现。(9) 返回主菜单。方便用户随时查看主菜单,并选择功能。通过调用 SubMainMenu ( ) 函数来实现。3
5、 模块设计1 模块设计本程序主要包含两个模块:主程序模块和链表操作模块。其调用关系如下图:主程序模块 链表操作模块系统初始化模块文件处理模块3.2 系统子程序及功能设计本系统共设计了 23 个子程序,各个函数的函数名及功能说明如下。( 1 ) int MainMenu( int k ); /主菜单选择( 1.1 ) void SubMainMenu();( 1.2 ) void CustomColor(WORD ForeColor,WORD BackColor); /自定义文字显示前景,背景色( 2 ) pCity CreateCityInfo(pCity Head); / 城市链表建立 (
6、3 ) void PrintOne (pCity ); /打印一条( 3.1 ) void PrintAll (pCity p); / 打印所有 ( 4 ) void SearchInfo(pCity Head); /查找 ( 4.1 ) pCity SearchUseName(pCity Head); /用名字查找( 4.2 ) pCity SearchUseCo(pCity Head); /用坐标查找( 4.3) pCity SearchInDis(pCity Head); /用距离查找( 5 ) void InsertInfo(pCity Head); /插入( 6 ) void Del
7、Info(pCity Head); /删除信息( 6.1 ) void DelUseName(pCity Head); /删除按姓名( 6.2 ) void DelUseCo(pCity Head); /删除按坐标( 7 ) void UpInfo(pCity Head); /修改信息( 7.1 ) void UpUseName(pCity Head); /修改用名字( 7.2 ) void UpUseCo(pCity Head); /修改用坐标( 7.3 ) void UpDetail(pCity p); /修改具体每一项 ( 8 ) void InitSetting(); /初始化用户设置
8、( 9 ) void UserSetting(); /用户设置( 10 ) pCity FileHandle(pCity Head); /文件处理( 11 ) int YNChoice(); /专门执行 Y/N 选择,选是为 Y,不是为 N,其它无效 ( 12)int NumberChoice(int Min,int Max); /数字选择,返回 Min 到 Max 之间的一个数 3 函数主要调用关系图本系统函数主要调用关系图如下所示,图中数字是各函数的标编号。Main()11.11.2233.144.14.24.3566.16.277.1 7.27.310894 详细设计1 数据类型定义(1
9、)本系统采用链式存储结构存储城市节点,节点定义如下:struct Coordint x;int y;typedef struct Citychar Name20;Coord Co;int People;int Area;City *Next; *pCity;2 系统主要子程序设计(1) 建立链表函数,用来建立城市链表pCity CreateCityInfo(pCity Head) / 城市链表建立 pCity DelCity,Tem;if (Head)printf(“链表已近存在,确定重新建立 (Y/N) “);if(YNChoice()DelCity=Head-Next;while (Del
10、City) /删除所有Tem=DelCity-Next;free(DelCity);DelCity=Tem;Head=NULL;elsereturn Head;Head=(pCity)malloc(LEN); /建立头结点Head-Next=NULL;char Name20;int Jum; /跳出输入循环用COORD Co;int People;int Area;int k=1; int i=1; /控制 while 里的循环printf(“请输入城市的名称:“);fflush(stdin);gets(Name);printf(“请输入 %s 的坐标,形如(X Y):“,Name);fflu
11、sh(stdin);scanf(“%d%d“,printf(“请输入 %s 的人口:“,Name);fflush(stdin);scanf(“%d“,printf(“请输入 %s 的面积:“,Name);fflush(stdin);scanf(“%d“,Jum=1;while(Jum)pCity Tem=(pCity)malloc(LEN);if(k!=1)printf(“请输入城市的名称:“);fflush(stdin);gets(Name);printf(“请输入 %s 的坐标,形如(X Y):“,Name);fflush(stdin);scanf(“%d%d“,printf(“请输入 %
12、s 的人口:“,Name);fflush(stdin);scanf(“%d“,printf(“请输入 %s 的面积:“,Name);fflush(stdin);scanf(“%d“,strcpy(Tem-Name,Name);Tem-Co.X=Co.X;Tem-Co.Y=Co.Y;Tem-People=People;Tem-Area=Area;Tem-Next=Head-Next;Head-Next=Tem; /连接了连个结点printf(“信息录入成功,是否继续添加:(Y/N)“);Jum=YNChoice();i=1;k+;return Head;(2) 显示所有节点的信息,用于查看城市链
13、表。void PrintOne(pCity p)printf(“tt%-16s( %3d,%-3d)t%-9d%-8dn“,p-Name,p-Co.x,p-Co.y,p-People,p-Area);void PrintAll(pCity p)if(p)printf(“全部城市信息为 :n“);printf(“tt 城市tt 坐标tt 人口t 面积n“);while(p=p-Next)PrintOne(p);elseprintf(“链表未建立,请先建立链表n“);5 测试分析系统各运行界面如下,各子功能测试结果如下。5.1 建立城市链表在主菜单下(或“主菜单功能选项下” ) ,用户输入 1 并
14、回车,然后按照提示建立城市链表,分别输入每个城市的名称,坐标,人口和面积,运行结构如下图:5.2 浏览城市链表在主菜单下(或“主菜单功能选项下” ) ,用户输入 2 并回车,可以浏览链表中的全部内容,结构如下5.3 城市链表的查找在主菜单下(或“主菜单功能选项下” ) ,用户输入 3 并回车,可以进入查找子菜单,如图:用户输入相应选项即可进入相应功能。5.4 城市链表的插入在主菜单下(或“主菜单功能选项下” ) ,用户输入 4 并回车,可以进入插入功能,按照提示输入城市信息,即可插入新的城市信息。界面如下 5.5 城市链表的删除在主菜单下(或“主菜单功能选项下” ) ,用户输入 5 并回车,可
15、以进入删除子菜单,按照提示输入要删除的城市,即可删除该城市信息。界面如下 5.6 城市链表的更新在主菜单下(或“主菜单功能选项下” ) ,用户输入 6 并回车,可以进入删除子菜单,按照提示输入要删除的城市,即可删除该城市信息。界面如下 5.7 查看给定范围内的城市在主菜单下(或“主菜单功能选项下” ) ,用户输入 7 并回车,可以进入查看给定范围内的城市的高级功能,按照提示输入中心坐标,然后在给定一个范围,即可查找出在该范围内的所有城市。界面如下:5.8 文件的载入与保存在主菜单下(或“主菜单功能选项下” ) ,用户输入 8 并回车,可以进入文件载入与保存的选择功能,可以在其中载入文件数据到链
16、表,也可以将链表中的数据保存到指定位置,子菜单如下5.9 系统设置 在主菜单下(或“主菜单功能选项下” ) ,用户输入 9 并回车,可以进入系统设置功能,可以设置系统显示的文字颜色和显示背景色,还可以调整文字的大小,用户所做的更改将会自动保存,下次使用时不必重新设置,子菜单如下:6 源程序清单6.1 公共头文件“Common.h”#include #include #include #include #include #include #define LEN sizeof(City)typedef struct Citychar Name20;COORD Co;int People;int A
17、rea;City *Next; *pCity;int MainMenu(int k); /主菜单选择void Welcome();void SubMainMenu();void ColorSetting(int Word,int Back); /自定义文字显示前景,背景色pCity CreateCityInfo(pCity Head); / 城市链表建立 void PrintOne (pCity ); /打印一条void PrintAll (pCity p); / 打印所有 void SearchInfo(pCity Head); /查找 pCity SearchUseName(pCity H
18、ead); /用名字查找pCity SearchUseCo(pCity Head); /用坐标查找void InsertInfo(pCity Head); /插入pCity SearchInDis(pCity Head); /用距离查找pCity DelInfo(pCity Head); /删除信息void DelUseName(pCity Head); /删除按姓名void DelUseCo(pCity Head); /删除按坐标pCity DelAll(pCity Head);void UpInfo(pCity Head); /修改信息void UpUseName(pCity Head);
19、 /修改用名字void UpUseCo(pCity Head); /修改用坐标void UpDetail(pCity p); /修改具体每一项 int YNChoice(); /专门执行 Y/N 选择,选是为 Y,不是为 N,其它无效int NumberChoice(int Min,int Max); /数字选择,返回 Min 到 Max 之间的一个数 void Suspand();void InitSetting(); /初始化用户设置pCity FileHandle(pCity Head); /文件处理void UserSetting(); /用户设置“File.h”#include #d
20、efine _WIN32_WINNT 0x0500extern “C“ WINBASEAPI HWND WINAPI GetConsoleWindow ();void SaveFile(char * SaveDirectory,pCity Head);pCity OpenFile(char * OpenDirectory,pCity Head);void Save(HANDLE hFile,char * SaveDirectory,pCity Head);void LSaveFile(char *SaveDirectory);pCity open(char *OpenDirectory,pCi
21、ty Head);“Setting.h”struct UserSet /用户设置int sFontNumber;int sFontColor;int sBackgroundColor;char Director200;struct CONSOLE_FONT /字体设置DWORD index;COORD dim;typedef BOOL (WINAPI *PROCSETCONSOLEFONT)(HANDLE, DWORD);PROCSETCONSOLEFONT SetConsoleFont;WORD BasicColor8=FOREGROUND_RED,FOREGROUND_GREEN,FORE
22、GROUND_BLUE,BACKGROUND_RED,BACKGROUND_GREEN,BACKGROUND_BLUE,FOREGROUND_INTENSITY,BACKGROUND_INTENSITY,;WORD FontColor9=BasicColor0,BasicColor1,BasicColor2,BasicColor0|BasicColor1,BasicColor0|BasicColor2,BasicColor1|BasicColor2,BasicColor0|BasicColor1|BasicColor3,BasicColor0|BasicColor1|BasicColor3|B
23、asicColor6,0 ;WORD BackColor9=BasicColor3,BasicColor4,BasicColor5,BasicColor3|BasicColor4,BasicColor3|BasicColor5,BasicColor4|BasicColor5,BasicColor3|BasicColor4|BasicColor5,BasicColor3|BasicColor4|BasicColor5|BasicColor7,0 ;void ColorSetting();void FontSetting();“Welcome.h”typedef HWND (WINAPI *PRO
24、CGETCONSOLEWINDOW)();PROCGETCONSOLEWINDOW GetConsoleWindow;6.2 各函数文件“Common.cpp”#include “Common.h“int YNChoice() /专门执行 Y/N 选择,选是为 Y,不是为 N,其它无效char Jump,k=1;dofflush(stdin);if (k!=1)printf(“选择有误,请重新选择 (Y/N): “);Jump=getchar();k+;while(!(Jump=Y|Jump=y|Jump=N|Jump=n);if (Jump=Y|Jump=y)return 1;elseret
25、urn 0; int NumberChoice(int Min,int Max)int k=0;int x;dofflush(stdin);if(k)printf(“选择有误,请重新选择:“);scanf(“%d“,k+;while(xMax);return x;void Suspand()fflush(stdin);getchar();“Creaete.cpp”#include “Common.h“pCity CreateCityInfo(pCity Head) / 城市链表建立 pCity DelCity,Tem;if (Head)printf(“链表已近存在,确定重新建立 (Y/N) “
26、);if(YNChoice()DelCity=Head-Next;while (DelCity) /删除所有Tem=DelCity-Next;free(DelCity);DelCity=Tem;Head=NULL;elsereturn Head;Head=(pCity)malloc(LEN); /建立头结点Head-Next=NULL;char Name20;int Jum; /跳出输入循环用COORD Co;int People;int Area;int k=1; int i=1; /控制 while 里的循环printf(“请输入城市的名称:“);fflush(stdin);gets(Na
27、me);printf(“请输入 %s 的坐标,形如(X Y):“,Name);fflush(stdin);scanf(“%d%d“,printf(“请输入 %s 的人口:“,Name);fflush(stdin);scanf(“%d“,printf(“请输入 %s 的面积:“,Name);fflush(stdin);scanf(“%d“,Jum=1;while(Jum)pCity Tem=(pCity)malloc(LEN);if(k!=1)printf(“请输入城市的名称:“);fflush(stdin);gets(Name);printf(“请输入 %s 的坐标,形如(X Y):“,Nam
28、e);fflush(stdin);scanf(“%d%d“,printf(“请输入 %s 的人口:“,Name);fflush(stdin);scanf(“%d“,printf(“请输入 %s 的面积:“,Name);fflush(stdin);scanf(“%d“,strcpy(Tem-Name,Name);Tem-Co.X=Co.X;Tem-Co.Y=Co.Y;Tem-People=People;Tem-Area=Area;Tem-Next=Head-Next;Head-Next=Tem; /连接了连个结点printf(“信息录入成功,是否继续添加:(Y/N)“);Jum=YNChoice
29、();i=1;k+;return Head;“Delete.cpp”#include “Common.h“pCity DelInfo(pCity Head)int Choice,k=1;if(!Head)printf(“链表未建立,请先建立链表n“);return Head;system(“cls“);printf(“ *删除选项*n“);printf(“ * 1.按名字 *n“);printf(“ * 2.按坐标 *n“);printf(“ * 3.删除全部 *n“);printf(“ * 0.返回主菜单 *n“);printf(“ *n“);printf(“请选择删除方式: “);Choi
30、ce=NumberChoice(0,3);switch (Choice)case 1 :DelUseName(Head);break;case 2 :DelUseCo(Head);case 3:Head=DelAll(Head);break;default:break;return Head;void DelUseName(pCity Head) /删除按姓名pCity p=Head,q=Head-Next,t;char CityName20;printf(“请输入要删除的城市名称:“);fflush(stdin);gets(CityName);while (q)if (!strcmp(Cit
31、yName,q-Name)break;p=q;q=q-Next;if (q)t=q;p-Next=q-Next;free(t);printf(“删除成功!n“); elseprintf(“没有找到指定城市,删除失败!n“);Suspand();void DelUseCo(pCity Head) /删除按坐标int x , y ;pCity p= Head , q = Head-Next,t;printf(“请输入城市坐标,形如(X Y):n“);scanf(“%d%d“,while (q)if (p-Co.X=xp=q;q=q-Next;if (q)t=q;p-Next=q-Next;free
32、(t);printf(“删除成功!n“); elseprintf(“没有找到指定城市,删除失败!n“);Suspand();pCity DelAll(pCity Head)pCity p= Head-Next , q ;while (p)q=p-Next;free(p);p=q; Head=NULL;printf(“删除成功n“);Suspand();return Head;“Insert.cpp”#include “Common.h“void InsertInfo(pCity Head) /插入pCity p=Head;char CityName30=0;char szName30=0;CO
33、ORD Co;int People;int Area;if(!Head)printf(“链表未建立,请先建立链表n“);Suspand();return ;fflush(stdin);printf(“请输入城市的名称:“);gets(CityName);fflush(stdin);printf(“请输入 %s 的坐标,形如(X Y):“,CityName);scanf(“%d%d“,fflush(stdin);printf(“请输入 %s 的人口:“,CityName);scanf(“%d“,fflush(stdin);printf(“请输入 %s 的面积:“,CityName);scanf(
34、“%d“,while(p-Next)p=p-Next;pCity Tem=(pCity)malloc(LEN);strcpy(Tem-Name,CityName);Tem-Co.X=Co.X;Tem-Co.Y=Co.Y;Tem-People=People;Tem-Area=Area;Tem-Next=p-Next;p-Next=Tem;printf(“插入链表成功!n“);Suspand();“Menu.cpp”#include “Common.h“int MainMenu(int k) int Choice,i=1;system(“cls“);if(!k)printf(“ *欢迎使用城市信息
35、系统*n“);printf(“ * 1. 城市链表建立 *n“);printf(“ * 2. 城市链表浏览 *n“);printf(“ * 3. 城市链表的查找 *n“);printf(“ * 4. 城市链表插入 *n“);printf(“ * 5. 城市链表删除 *n“);printf(“ * 6. 城市链表更新 *n“);printf(“ * 7. 文件载入和保存 *n“);printf(“ * 8. 设置 *n“);printf(“ * 9. 显示主菜单 *n“);printf(“ * 0. 退出系统 *n“);printf(“ *n“);else SubMainMenu();print
36、f(“请选择功能: “);Choice=NumberChoice(0,9);return Choice;void SubMainMenu()printf(“ *n“);printf(“ * 1. 城市链表建立 *n“);printf(“ * 2. 城市链表浏览 *n“);printf(“ * 3. 城市链表的查找 *n“);printf(“ * 4. 城市链表插入 *n“);printf(“ * 5. 城市链表删除 *n“);printf(“ * 6. 城市链表更新 *n“);printf(“ * 7. 文件载入和保存 *n“);printf(“ * 8. 设置 *n“);printf(“ *
37、 9. 显示主菜单 *n“);printf(“ * 0. 退出系统 *n“);printf(“ *n“);“Printf.cpp”#include “Common.h“void PrintOne(pCity p)printf(“tt%-16s( %3d,%-3d)t%-9d%-8dn“,p-Name,p-Co.X,p-Co.Y,p-People,p-Area);void PrintAll(pCity p)if(p)printf(“全部城市信息为 :n“);printf(“tt 城市tt 坐标tt 人口t 面积n“);while(p=p-Next)PrintOne(p);elseprintf(“
38、链表未建立,请先建立链表n“);Suspand();“Search.cpp”#include “Common.h“void SearchInfo(pCity Head) /查找int Choice;pCity pResult;system(“cls“);if(Head)printf(“ *查找方式*n“);printf(“ * 1.按名称 *n“);printf(“ * 2.按坐标 *n“);printf(“ * 3.查找离城市 X 距离 Y 内的城市 *n“);printf(“ * 0 返回主菜单 *n“);printf(“ *n“);printf(“请输入您的查找方式:“);Choice=
39、NumberChoice(0,3);switch (Choice)case 1:if(pResult=SearchUseName(Head)printf(“找到了该城市:n“);printf(“tt 城市tt 坐标tt 人口t 面积n“);PrintOne(pResult);elseprintf(“抱歉!没有找到您要找的城市!n“);Suspand();break;case 2:if(pResult=SearchUseCo(Head)printf(“找到了该城市:n“);printf(“tt 城市tt 坐标tt 人口t 面积n“);PrintOne(pResult);elseprintf(“抱
40、歉!没有找到您要找的城市!n“);Suspand();break;case 3:SearchInDis(Head);Suspand();break;default:break;elseprintf(“链表未建立,请先建立链表n“);Suspand();pCity SearchUseName(pCity Head) /用名字查找char CityName20;pCity p=Head;printf(“请输入城市名:“);fflush(stdin);gets(CityName);while (p=p-Next)if (!strcmp(CityName,p-Name)break;return p;p
41、City SearchUseCo(pCity Head) /用坐标查找int x,y;pCity p=Head;printf(“请输入城市坐标,形如(X Y):“);scanf(“%d%d“,while (p=p-Next)if (p-Co.X=xreturn p;pCity SearchInDis(pCity Head) /用距离查找int Dis,x,y,k=0;pCity q=Head;if(!Head)printf(“链表未建立,请先建立链表n“);return NULL;printf(“请给定一个坐标,形如(X Y):“);fflush(stdin);scanf(“%d%d“,pri
42、ntf(“请给定一个距离:“);fflush(stdin);scanf(“%d“,while (q=q-Next)if(x-q-Co.X)*(x-q-Co.X)+(y-q-Co.Y)*(y-q-Co.Y)Name,Name);printf(“是否修改坐标(Y/N) ? “);if (YNChoice()printf(“请输入新坐标,形如(X Y) ? “);scanf(“%d%d“,p-Co.X=Co.X;p-Co.Y=Co.Y;printf(“是否修改人口(Y/N) ? “);if (YNChoice()printf(“请输入新的人口数据:“);scanf(“%d“,p-People=People;printf(“是否修改面积(Y/N) ? “);if(YNChoice()printf(“请输入新面积:“);scanf(“%d“,p-Area=Area;printf(“ 修改成功!n“);Suspand();“UserSettting.cpp”#include “Common.h“#include “Setting.h“HANDLE hSetFile;UserSet DefSet=11,1,2,“0“; /全局变量,用于保存用户