C++实现电子地图管理系统

电子地图信息管理系统!!!

刚刚完成实训
三天的时间完成了电子地图管理系统
遇到不少困难但最后还是完成了项目
功能包括:读取dat文件,添加道路信息,五种排序算法,两种检索算法,更新数据文件,
自动比较不同排序算法性能在这里插入图片描述
还有不少不足,日后慢慢改善
参考代码:C语言实现
不bb了,上代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<string.h>
#include<Windows.h>

//宏函数处理二进制数据
#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 99999 

using namespace std;

static int sizecount = 0;//记录道路记录条数
static int sizecount2 = 0;//记录道路记录条数/用于性能分析算法

int mark1 = 0;//标记是否读取过文件
int mark2 = 0;//标记是否完成过排序

static int Sort_Time[5][2];//存放排序所花费时间——格式:Sort_Time[s][ms]

class RoadRecord			//定义道路信息的类
{
private:
	short int InfoSize;		//信息尺寸2byte
	long int LinkID;		//4byte
	short NameSize;			//道路名字大小2byte
	/*NodeInfo : 4byte*/
	int DispClass;			// 分类番号0~3
	int Brunch;				// 分叉数量4~6
	int NameFlag;			// 有无名字的标志7
	char RoadName[20];		// 道路名字8~31
public:
	/*运算符> < = <= >=的重载*/
	int operator >(const RoadRecord &x)
	{
		if (LinkID > x.LinkID)
			return 1;
		else
			return 0;
	}
	int operator <(const RoadRecord &x)
	{
		if (LinkID < x.LinkID)
			return 1;
		else
			return 0;
	}
	int operator<=(const RoadRecord &x)
	{
		if (LinkID <= x.LinkID)
			return 1;
		else
			return 0;
	}
	int operator>=(const RoadRecord &x)
	{
		if (LinkID >= x.LinkID)
			return 1;
		else
			return 0;
	}
	/*赋值运算符重载,用于交换类对象成员数据*/
	RoadRecord operator =(const RoadRecord &c)
	{
		InfoSize = c.InfoSize;
		LinkID = c.LinkID;
		NameSize = c.NameSize;
		DispClass = c.DispClass;
		Brunch = c.Brunch;
		NameFlag = c.NameFlag;
		memcpy(RoadName, c.RoadName, 20);
		return *this;
	}
	/*对象和整型数据的运算符重载*/
	bool operator==(int x)
	{
		if (this->LinkID == x)
			return true;
		else
			return false;
	}
	bool operator>(int x)
	{
		if (this->LinkID > x)
			return true;
		else
			return false;
	}
	bool operator<(int x)
	{
		if (this->LinkID < x)
			return true;
		else
			return false;
	}
	/**************************************************************************************
	*	Functionname:RoadRecord::disp													  *
	*	Function Description:显示类对象成员数据											  *
	*	Date:2019/11/12																      *
	**************************************************************************************/
	void disp()
	{
		cout << "#   LinkID=" << LinkID << '\t';
		cout << "  NameFlag=" << NameFlag << '\t';
		cout << "Brunch=" << Brunch << '\t';
		cout << "      DispClass=" << DispClass << '\t';
		if (NameFlag == 1)
			cout << "RoadName=" << RoadName << '\t' << "#" << endl;
		else
			cout << "RoadName=" << "无   #" << endl;
	}
	operator long int()//变换构造函数获取LinkID
	{
		return LinkID;
	}
	friend void Add_Record(RoadRecord rr[]);
	friend int Read_File_Data(RoadRecord rr[]);
	friend int Temporary_Read(RoadRecord rr[]);
	friend void Sort(RoadRecord A[], int N);
	friend int Write_Result(int j, int count[], RoadRecord rr[]);
	friend int Search_Data(RoadRecord rr[]);
	friend int Update(RoadRecord rr[]);
};

/*获取系统当前时间*/
void Gettime()
{
	SYSTEMTIME sys;
	GetLocalTime(&sys);
	printf("%02d:%02d:%02d.%03d\n", sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
}

/**************************************************************************************
*	Functionname:Read_File_Data														  *
*	Function Description:读取二进制文件,并将其解析在文本文档里						  *
*	Date:2019/11/12																      *
*	参考C语言代码转化为C++代码编译成功												  *
**************************************************************************************/
int Read_File_Data(RoadRecord rr[])
{
	int m;//用于处理4byte的NodeInfo
	sizecount = 0;//初始化数组长度避免溢出
	char actotalsize[2];//利用字符数组获取需读出文件的长度
	char aclinkid[4];
	char acroadnamesize[2];
	char acNodeInfo[4];

	unsigned short ustotalsize;//us/ul变量存放处理后的二进制数据并赋给对象数组
	unsigned long ullinkid;
	unsigned short usroadnamesize;

	//ifstream inFile("d:\\new_GTBL.dat", ios::in | ios::binary);//用于判断更新文件是否成功
	ifstream inFile("d:\\GTBL.dat", ios::in | ios::binary);
	ofstream outFile("d:\\GTBL.txt", ios::out);
	cout << "正在打开文件D:\\GTBL.dat以及创建文件D:\\GTBL.txt..." << endl;

	if (!inFile) {//检查GTBL.dat是否打开成功
		cout << "找不到文件GTBL.dat!" << endl;
		return 0;
	}

	if (!outFile) {//检查GTBL.txt是否打开/创建成功
		cout << "找不到文件GTBL.txt!" << endl;
		return 0;
	}

	cout << "正在将地图信息写入GTBL.txt..." << endl;

	while (inFile.read(actotalsize, sizeof(actotalsize))) {
		/*读文件操作,sizeof(字符数组)来获取需读入的位长*/
		inFile.read(aclinkid, sizeof(aclinkid));
		inFile.read(acroadnamesize, sizeof(acroadnamesize));
		inFile.read(acNodeInfo, sizeof(acNodeInfo));

		/*调用宏函数 , 将字符串信息转化为数值类型*/
		ustotalsize = MCGETSHORT(actotalsize);
		ullinkid = MCGETLONG(aclinkid);
		usroadnamesize = MCGETSHORT(acroadnamesize);

		/*赋值给对象数组*/
		rr[sizecount].InfoSize = ustotalsize;
		rr[sizecount].LinkID = ullinkid;
		rr[sizecount].NameSize = usroadnamesize;

		/*利用m处理NodeInfo的二进制数据以获得Node情报并赋值*/
		m = (int)acNodeInfo[3] & 255;
		rr[sizecount].DispClass = m & 15;
		rr[sizecount].Brunch = (m & 112) / 16;
		rr[sizecount].NameFlag = (m & 128) / 128;

		/*获取道路名称(ustotalsize-12为道路名称所占byte长)*/
		inFile.read(rr[sizecount].RoadName, ustotalsize - 12);

		/*将道路数据写入创建的txt文本文档*/
		outFile << "#" << '\t' << "LinkID=" << rr[sizecount].LinkID << '\t';
		outFile << "flag=" << rr[sizecount].NameFlag << '\t';
		outFile << "brunch=" << rr[sizecount].Brunch << '\t';
		outFile << "dispclass=" << rr[sizecount].DispClass << '\t';
		if (rr[sizecount].NameFlag == 1)
			outFile << "Roadname=1=" << rr[sizecount].RoadName + 4 << '\t' << "#" << endl;
		else
			outFile << "Roadname=1=" << '\t' << "#" << endl;

		/*if(rr[sizecount].NameFlag==1)
			cout << rr[sizecount].InfoSize << "\t" << rr[sizecount].LinkID << "\t" 
			<< rr[sizecount].NameSize << "\t" << rr[sizecount].dispclass << "\t"
			<< rr[sizecount].brunch << "\t" << rr[sizecount].NameFlag << "\t" << rr[sizecount].RoadName << endl;
		else
			cout << rr[sizecount].InfoSize << "\t" << rr[sizecount].LinkID << "\t" 
			<< rr[sizecount].NameSize << "\t" << rr[sizecount].dispclass << "\t"
			<< rr[sizecount].brunch << "\t" << rr[sizecount].NameFlag << endl;*/

		sizecount++;
	}
	cout << "数据读取成功!" << endl;
	mark1++;
	/*关闭文件*/
	inFile.close();
	outFile.close();
	system("pause");
	return 0;
}

/**************************************************************************************
*	Functionname:Temporary_Read													      *
*	Function Description:读取二进制文件存入类对象(暂时供排序性能比较使用)	          *
*	Date:2019/11/14																      *
*	参考C语言代码转化为C++代码编译成功												  *
**************************************************************************************/
int Temporary_Read(RoadRecord rr[])
{
	int m;//用于处理4byte的NodeInfo
	sizecount2 = 0;//初始化数组长度避免溢出
	char actotalsize[2];//利用字符数组获取需读出文件的长度
	char aclinkid[4];
	char acroadnamesize[2];
	char acNodeInfo[4];

	unsigned short ustotalsize;//us/ul变量存放处理后的二进制数据并赋给对象数组
	unsigned long ullinkid;
	unsigned short usroadnamesize;

	//ifstream inFile("d:\\new_GTBL.dat", ios::in | ios::binary);//用于判断更新文件是否成功
	ifstream inFile("d:\\GTBL.dat", ios::in | ios::binary);
	if (!inFile) {//检查GTBL.dat是否打开成功
		cout << "找不到文件GTBL.dat!" << endl;
		return 0;
	}

	while (inFile.read(actotalsize, sizeof(actotalsize))) {
		/*读文件操作,sizeof(字符数组)来获取需读入的位长*/
		inFile.read(aclinkid, sizeof(aclinkid));
		inFile.read(acroadnamesize, sizeof(acroadnamesize));
		inFile.read(acNodeInfo, sizeof(acNodeInfo));

		/*调用宏函数 , 将字符串信息转化为数值类型*/
		ustotalsize = MCGETSHORT(actotalsize);
		ullinkid = MCGETLONG(aclinkid);
		usroadnamesize = MCGETSHORT(acroadnamesize);

		/*赋值给对象数组*/
		rr[sizecount2].InfoSize = ustotalsize;
		rr[sizecount2].LinkID = ullinkid;
		rr[sizecount2].NameSize = usroadnamesize;

		/*利用m处理NodeInfo的二进制数据以获得Node情报并赋值*/
		m = (int)acNodeInfo[3] & 255;
		rr[sizecount2].DispClass = m & 15;
		rr[sizecount2].Brunch = (m & 112) / 16;
		rr[sizecount2].NameFlag = (m & 128) / 128;

		/*获取道路名称(ustotalsize-12为道路名称所占byte长)*/
		inFile.read(rr[sizecount2].RoadName, ustotalsize - 12);
		
		sizecount2++;
	}
	/*关闭文件*/
	inFile.close();
	return 0;
}

/**************************************************************************************
*	Functionname:add_record															  *
*	Function Description:添加道路信息至对象数组尾部          						  *
*	Date:2019/11/13																      *
**************************************************************************************/
void Add_Record(RoadRecord rr[])
{
	char opt = 'Y';
	while (opt != 'N') {
		cout << "开始添加道路信息!" << endl;
		cout << "请依次输入InfoSize/LinkID/NameSize/Class/Brunch/Flag/Name:" << endl;
		cin >> rr[sizecount].InfoSize >> rr[sizecount].LinkID >> rr[sizecount].NameSize >>
			rr[sizecount].DispClass >> rr[sizecount].Brunch >> 
			rr[sizecount].NameFlag >> rr[sizecount].RoadName;
		sizecount++;
		cout << "添加完成!" << endl;
		cout << "是否继续添加道路信息?(Y/N)" << endl;
		cin >> opt;
	}
	cout << "返回功能菜单..." << endl;
	system("pause");
}

//冒泡排序
void Bubble_Sort(RoadRecord A[], int N)
{
	int i, j;
	bool change;//记录是否还有交换操作,如果没有则排序结束
	RoadRecord temp;
	for (i = N - 1, change = true; i >= 1 && change; --i)//外循环
	{
		change = false;
		for (j = 0; j < i; ++j)//内循环
			if (A[j] > A[j + 1])
			{
				temp = A[j];
				A[j] = A[j + 1];
				A[j + 1] = temp;
				change = true;
			}
	}
	cout << "冒泡排序完成!" << endl;
}
//直接插入排序
void Insertion_Sort(RoadRecord A[], int N)
{
	int i, j;
	RoadRecord temp;
	for (i = 1; i < N; i++)
	{
		temp = A[i];
		for (j = i - 1; j >= 0 && temp < A[j]; j--)
		{
			if (A[j - 1] > temp)
				A[j + 1] = A[j];//比当前元素小的往后移动
		}
		A[j + 1] = temp;//将当前元素插入到合适的位置
	}
	cout << "插入排序完成!" << endl;
}
//希尔排序
void Shell_Sort(RoadRecord A[], int N)
{
	int i, j, Increment;
	RoadRecord temp;
	for (Increment = N / 2; Increment > 0; Increment /= 2)
		for (i = Increment; i < N; i++) {
			temp = A[i];
			for (j = i; j >= Increment; j -= Increment)
				if (temp < A[j - Increment])
					A[j] = A[j - Increment];
				else
					break;
			A[j] = temp;
		}
	cout << "希尔排序完成!" << endl;
}
//归并排序
void Merge(RoadRecord A[], RoadRecord temp[], int lpos, int rpos, int rightend)
{
	int i, leftend, num, tempPos;
	leftend = rpos - 1;
	tempPos = lpos;
	num = rightend - lpos + 1;
	while (lpos <= leftend && rpos <= rightend)
		if (A[lpos] <= A[rpos])
			temp[tempPos++] = A[lpos++];
		else
			temp[tempPos++] = A[rpos++];
	while (lpos <= leftend)
		temp[tempPos++] = A[lpos++];
	while (rpos <= rightend)
		temp[tempPos++] = A[rpos++];
	for (i = 0; i < num; i++, rightend--)
		A[rightend] = temp[rightend];
}
void MSort(RoadRecord A[], RoadRecord temp[], int left, int right)
{
	int center;
	if (left < right)
	{
		center = (left + right) / 2;
		MSort(A, temp, left, center);
		MSort(A, temp, center + 1, right);
		Merge(A, temp, left, center + 1, right);
	}
}
void Merge_Sort(RoadRecord A[], int N)
{
	RoadRecord *temp;
	temp = (RoadRecord *)malloc(N * sizeof(RoadRecord));
	if (temp != NULL)
	{
		MSort(A, temp, 0, N - 1);
		free(temp);
	}
	else
		cout << "No more Space" << endl;
	cout << "归并排序完成!" << endl;
}
//基数排序
void Base_Sort(RoadRecord A[], int N)
{
	//申请一个临时数组的内存
	RoadRecord *temp = (RoadRecord *)malloc(N * sizeof(RoadRecord));
	for (int i = 0; i < N; i++)
		if (A[i] > 80000)
			temp[0] = A[i];
		else
			temp[A[i]] = A[i];//这里要调用变换构造函数
	//将数据写回原来数组
	A[N - 1] = temp[0];//temp[0]是最大的数据妨到最后
	for (int i = 1; i < N; i++)
		A[i - 1] = temp[i];
	//程序调用结束将释放临时数组内存
	free(temp);
	cout << "基数排序完成!" << endl;
}
//快速排序
/*void Quick_Sort(RoadRecord A[], int low, int high)
{
	if (low < high){
		int i = low, j = high;
		RoadRecord pivokey = A[low];
		while (i < j){
			while (i < j && A[j] >= pivokey) j--;
			if (i < j)
				A[i++] = A[j];
			while (i < j && A[i] <= pivokey) i++;
			if (i < j)
				A[j--] = A[i];
		}
		A[i] = pivokey;
		Quick_Sort(A, low, i - 1);
		Quick_Sort(A, i + 1, high);
	}
}*/

/**************************************************************************************
*	Functionname:Sort															      *
*	Function Description:排序算法程序,并获取排序时间    						  *
*	Date:2019/11/14																      *
**************************************************************************************/
void Sort(RoadRecord A[], int N)
{
	SYSTEMTIME sys1, sys2;//定义开始时时间对象和完成后时间对象
	int select;//定义选择变量并初始化
	cout << "请选择排序方法:" << endl;
	cout << "1.Bubble_Sort" << endl << "2.Insert_Sort" << endl << "3.Shell_Sort" 
		<< endl << "4.Merge_Sort" << endl << "5.Base_Sort" << endl << "0.退出搜索模块" << endl;
	cout << "请选择:" << endl;
	cin >> select;
	while (select < 1 || select>5) {//处理输入选择变量错误的情况
		cout << "输入有误!请重新输入:" << endl;
		cin >> select;
	}
	if (select != 0) {
		GetLocalTime(&sys1);//获取开始时间
		printf("开始时间为:%02d:%02d:%02d.%03d\n", 
			sys1.wHour, sys1.wMinute, sys1.wSecond, sys1.wMilliseconds);//显示开始时间
	}
	switch (select)
	{
	case 1:
		cout << "正在进行冒泡排序中..." << endl;
		Bubble_Sort(A, N);
		break;
	case 2:
		cout << "正在进行直接插入排序中..." << endl;
		Insertion_Sort(A, N);
		break;
	case 3:
		cout << "正在进行希尔排序中..." << endl;
		Shell_Sort(A, N);
		break;
	case 4:
		cout << "正在进行归并排序中..." << endl;
		Merge_Sort(A, N);
		break;
	case 5:
		cout << "正在进行基数排序中..." << endl;
		Base_Sort(A, N);
		break;
	case 0:
		break;
	}
	if (select != 0) {
		GetLocalTime(&sys2);//获取结束时间
		printf("结束时间为:%02d:%02d:%02d.%03d\n", 
			sys2.wHour, sys2.wMinute, sys2.wSecond, sys2.wMilliseconds);//显示结束时间
	}
	//计算排序过程花费时间(将分秒毫秒转换成秒单位显示)
	if (select != 0) {
		if (sys2.wMilliseconds < sys1.wMilliseconds) {
			if (sys2.wSecond < sys1.wSecond) {
				cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond) - 1 
					<< "." << sys1.wMilliseconds - sys2.wMilliseconds << "秒" << endl;
			}
			else {
				cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond) - 1 
					<< "." << sys1.wMilliseconds - sys2.wMilliseconds << "秒" << endl;
			}
		}
		else {
			if (sys2.wSecond < sys1.wSecond) {
				cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond) 
					<< "." << sys2.wMilliseconds - sys1.wMilliseconds << "秒" << endl;
			}
			else {
				cout << "排序时间为:" << (sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond) 
					<< "." << sys2.wMilliseconds - sys1.wMilliseconds << "秒" << endl;
			}
		}
	}
	cout << "已退出排序模块!" << endl;
	mark2++;
	system("pause");
}

/**************************************************************************************
*	Functionname:Write_Result														  *
*	Function Description:将检索到的大于5条的道路信息写入txt文本文档					  *
*	Date:2019/11/13																      *
**************************************************************************************/
int Write_Result(int j, int count[], RoadRecord rr[])
{
	int c;//暂时存放需显示对象数组下标
	ofstream outFile("d:\\search_flie.txt", ios::out);//创建文件
	if (!outFile) {//检查search_file.txt是否打开/创建成功
		cout << "找不到search_file.txt!" << endl;
		return 0;
	}
	cout << "正在写入文件..." << endl;
	for (int i = 0; i < j; i++) {
		c = count[i];

		outFile << "#" << '\t' << "LinkID=" << rr[c].LinkID << '\t';
		outFile << "flag=" << rr[c].NameFlag << '\t';
		outFile << "brunch=" << rr[c].Brunch << '\t';
		outFile << "dispclass=" << rr[c].DispClass << '\t';
		if (rr[c].NameFlag == 1)
			outFile << "Roadname=1=" << rr[c].RoadName + 4 << '\t' << "#" << endl;
		else
			outFile << "Roadname=1=" << '\t' << "#" << endl;
	}
	cout << "已写入文件search_file.txt" << endl;
	outFile.close();
	return 0;
}

//折半查找
int Half_Search(RoadRecord A[], int N, int target)
{
	int low, high, mid;
	//初始化low和high 
	low = 0; high = N - 1;
	mid = (low + high) / 2;
	while (low <= high)
	{
		if (A[mid] == target)
			return mid;
		if (A[mid] < target)//目标在右边
			low = mid + 1;
		else//目标在左边
			high = mid - 1;
		//更新mid
		mid = (low + high) / 2;
	}
	cout << "未找到目标LinkID!" << endl;
	return 0;
}

/**************************************************************************************
*	Functionname:Search_Data														  *
*	Function Description:根据用户需要检索的信息对道路信息进行检索					  *
*						 小于5条直接显示/大于5条写入文件search_file.txt				  *
*	Date:2019/11/12																      *
**************************************************************************************/
int Search_Data(RoadRecord rr[])
{
	int select;
	char opt = 'Y';
	int i, j, k, c;//i控制循环 j记录符合要求的信息条数 k作为count数组的下标计数器 c用于显示检索到的数据
	while (opt != 'N') {
		cout << "请选择需要搜索的信息:(小于等于五条直接显示,大于五条将写入文件D:\\search_flie.txt)" << endl;
		cout << "1.LinkID" << endl << "2.DispClass" << endl << "3.Brunch" << endl << "4.RoadName" << endl;
		cout << "0.退出搜索系统" << endl;
		cout << "请选择需要搜索的信息:" << endl;
		cin >> select;//功能选择

		if (select == 1) {//检索LinkID(因LinkID有序,使用折半查找)
			int LI;
			cout << "请输入需要搜索的LinkID(1-7位整数):" << endl;
			cin >> LI;
			/*for (i = 0; i < sizecount; i++) {
				if (rr[i].LinkID == LI) {
					cout << "搜索成功!" << endl;
					rr[i].disp();
				}
			}*/
			int f = Half_Search(rr, sizecount, LI);
			if (f) {
				rr[f].disp();
			}
		}

		else if (select == 2) {//检索DispClass
			int DC;
			k = 0;
			j = 0;
			cout << "请输入需要搜索的DispClass:" << endl;
			cin >> DC;
			for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
				if (rr[i].DispClass == DC) {
					j++;
				}
			}

			int *count = new int[j];//j个元素的数组用于存放符合条件的下标

			for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
				if (rr[i].DispClass == DC) {
					count[k] = i;
					k++;
				}
			}
			if (j == 0) {
				cout << "未找到符合要求的数据!" << endl;
			}
			else if (j <= 5) {//小于5个 直接显示
				cout << "搜索成功!直接显示:" << endl;
				for (i = 0; i < j; i++) {
					c = count[i];
					rr[c].disp();
				}
			}
			else if (j > 5) {//大于5个 写入文件
				cout << "搜索成功,结果大于5条!" << endl;
				Write_Result(j, count, rr);
			}
			delete[]count;
		}

		else if (select == 3) {//检索Brunch
			int BC;
			k = 0;
			j = 0;
			cout << "请输入需要搜索的Brunch:" << endl;
			cin >> BC;
			for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
				if (rr[i].Brunch == BC) {
					j++;
				}
			}

			int *count = new int[j];//j个元素的数组用于存放符合条件的下标

			for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
				if (rr[i].Brunch == BC) {
					count[k] = i;
					k++;
				}
			}
			if (j == 0) {
				cout << "未找到符合要求的数据!" << endl;
			}
			else if (j <= 5) {//小于5个 直接显示
				cout << "搜索成功!直接显示:" << endl;
				for (i = 0; i < j; i++) {
					c = count[i];
					rr[c].disp();
				}
			}
			else if (j > 5) {//大于5个 写入文件
				cout << "搜索成功,结果大于5条!" << endl;
				Write_Result(j, count, rr);
			}
			delete[]count;
		}

		else if (select == 4) {//检索RoadName
			char RN[20] = { 0 };
			k = 0;
			j = 0;
			cout << "请输入需要搜索的RoadName:" << endl;
			cin >> RN;
			for (i = 0; i < sizecount; i++) {//寻找符合条件的对象数量
				if (rr[i].NameFlag == 0) {}
				else if (strcmp(rr[i].RoadName + 4, RN) == 0) {
					j++;
				}
			}

			int *count = new int[j];//j个元素的数组用于存放符合条件的下标

			for (i = 0; i < sizecount; i++) {//将符合条件的对象下标存入count[j]
				if (rr[i].NameFlag == 0) {}
				else if (strcmp(rr[i].RoadName + 4, RN) == 0) {
					count[k] = i;
					k++;
				}
			}
			if (j == 0) {
				cout << "未找到符合要求的数据!" << endl;
			}
			else if (j <= 5) {//小于5个 直接显示
				cout << "搜索成功!直接显示:" << endl;
				for (i = 0; i < j; i++) {
					c = count[i];
					rr[c].disp();
				}
			}
			else if (j > 5) {//大于5个 写入文件
				cout << "搜索成功,结果大于5条!" << endl;
				Write_Result(j, count, rr);
			}
			delete[]count;
		}

		else if (select == 0) {
			cout << "退出检索模块!" << endl;
			return 0;
		}
		cout << "是否继续检索信息?(Y/N)" << endl;
		cin >> opt;
	}
	cout << "退出检索模块!" << endl;
	system("pause");
	return 0;
}

/**************************************************************************************
*	Functionname:Update																  *
*	Function Description:将增添好信息和排序完成的道路信息写入文件new_file.txt		  *
*	Date:2019/11/13																      *
**************************************************************************************/
int Update(RoadRecord rr[])
{
	ofstream outFile("d:\\new_file.txt", ios::out);//创建txt文档存放更新后的道路数据
	cout << "创建文件d:\\new_file.txt中..." << endl;
	if (!outFile) {//检查new_file.txt是否打开/创建成功
		cout << "ERROR!NO new_file.txt!" << endl;
		return 0;
	}
	cout << "正在将更新数据写入文件..." << endl;
	for (int i = 0; i < sizecount; i++) {//写入txt文本文档
		outFile << "#" << '\t' << "LinkID=" << rr[i].LinkID << '\t';
		outFile << "flag=" << rr[i].NameFlag << '\t';
		outFile << "brunch=" << rr[i].Brunch << '\t';
		outFile << "dispclass=" << rr[i].DispClass << '\t';
		if (rr[i].NameFlag == 1)
			outFile << "Roadname=1=" << rr[i].RoadName + 4 << '\t' << "#" << endl;
		else
			outFile << "Roadname=1=" << '\t' << "#" << endl;
	}
	cout << "更新成功!请前往d:\\new_file.txt查看更新结果!" << endl;
	outFile.close();
	system("pause");
	/*char pc[60];
	/*由于C++语言无法在读取txt文件的字符串时,设定遇到空格便结
	束的功能只能设定读取的边界,这使将读取txt文件中字符并传入
	dat文件中变得困难所以在本段程序中,使用了C语言的文件操作
	errno_t err;
	FILE *p2;			//文件指针p2用于打开new_file文件
	if ((err=fopen_s(&p2,"d:\\new_file.txt", "r") )!= NULL)	{//打开文件new_file为更新文件提供数据
		cout << "new_file.txt打开失败!" << endl;
		return 0;
	}

	FILE *p3;			//文件指针p3用来创建new_GTBL文件
	if ((err=fopen_s(&p3,"d:\\new_GTBL.dat", "wb")) != NULL){//判断文件创建是否成功
		cout << "new_GTBL.dat创建失败!" << endl;
		return 0;
	}

	cout<<"文件更新中..."<<endl;				//给出提示信息

	for (int i = 0; i < sizecount; i++)
	{
		fread(pc, 56, 1, p2);					//new_file文件信息->pc数组中
		fwrite(pc, 56, 1, p3);					//数组pc的信息->update二进制文件中
	}

	cout<<"文件更新成功!"<<endl<<"更新二进制数据存放在new_GTBL.dat文件中"<<endl;

	fclose(p2);
	fclose(p3);*/
	return 0;
}

/**************************************************************************************
*	Functionname:Analysis															  *
*	Function Description:依次使用五种排序算法并自动比较排序时间                		  *
*	Date:2019/11/13																      *
**************************************************************************************/
void Analysis()
{
	int i;
	SYSTEMTIME sys1, sys2;
	RoadRecord *A = new RoadRecord[Length];
	cout << "正在依次进行五种不同排序算法并进行性能分析..." << endl;
	for (i = 0; i < 5; i++) {//i控制每种排序的调用
		GetLocalTime(&sys1);
		switch (i) {
		case 0:
			Temporary_Read(A);//为临时类对象数组赋初值,来达到每次排序前数据序列都相同的目的
			Bubble_Sort(A, sizecount2);
			break;
		case 1:
			Temporary_Read(A);
			Insertion_Sort(A, sizecount2);
			break;
		case 2:
			Temporary_Read(A);
			Shell_Sort(A, sizecount2);
			break;
		case 3:
			Temporary_Read(A);
			Merge_Sort(A, sizecount2);
			break;
		case 4:
			Temporary_Read(A);
			Base_Sort(A, sizecount2);
			break;
		}
		GetLocalTime(&sys2);
		if (sys2.wMilliseconds < sys1.wMilliseconds) {
			if (sys2.wSecond < sys1.wSecond) {//为排序时间二维数组赋值
				Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond)) - 1;
				Sort_Time[i][1] = (sys1.wMilliseconds - sys2.wMilliseconds);
			}
			else {
				Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond) - 1);
				Sort_Time[i][1] = (sys1.wMilliseconds - sys2.wMilliseconds);
			}
		}
		else {
			if (sys2.wSecond < sys1.wSecond) {
				Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute - 1) * 60 - (sys1.wSecond - sys2.wSecond));
				Sort_Time[i][1] = (sys2.wMilliseconds - sys1.wMilliseconds);
			}
			else {
				Sort_Time[i][0] = ((sys2.wMinute - sys1.wMinute) * 60 + (sys2.wSecond - sys1.wSecond));
				Sort_Time[i][1] = (sys2.wMilliseconds - sys1.wMilliseconds);
			}
		}
	}
	cout << "分析完成!" << endl;
	cout << "*******算法性能比较*******" << endl;
	cout << "Means" << '\t' << '\t' << "TIME" << endl;//显示性能比较结果
	cout << "Bubble" << '\t' << '\t' << Sort_Time[0][0] << "." << Sort_Time[0][1] << "ms" << endl;
	cout << "Insertion" << '\t' << Sort_Time[1][0] << "." << Sort_Time[1][1] << "ms" << endl;
	cout << "Shell" << '\t' << '\t' << Sort_Time[2][0] << "." << Sort_Time[2][1] << "ms" << endl;
	cout << "Merge" << '\t' << '\t' << Sort_Time[3][0] << "." << Sort_Time[3][1] << "ms" << endl;
	cout << "Base" << '\t' << '\t' << Sort_Time[4][0] << "." << Sort_Time[4][1] << "ms" << endl;
	cout << "**************************" << endl;
	delete[]A;//释放内存
	system("pause");
}

/**************************************************************************************
*	Functionname:Menu																  *
*	Function Description:设计菜单调用各模块算法		                                  *
*	Date:2019/11/14   															      *
**************************************************************************************/
void Menu(RoadRecord rr[])
{
	int opt = 1;//选择变量
	while (opt != 0) {
		system("cls");
		cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
		cout << "*         -Welcome                                *" << endl;
		cout << "*                 -to                             *" << endl;
		cout << "*                    -电子地图管理系统-           *" << endl;
		cout << "*-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-*" << endl;
		cout << "*         1.读取文件(D:\\GTBL.dat)                 *" << endl;
		cout << "*         2.添加道路信息                          *" << endl;
		cout << "*         3.排序并显示算法性能(根据LinkID)        *" << endl;
		cout << "*         4.检索道路信息                          *" << endl;
		cout << "*         5.更新道路信息(D:\\new_file.txt)         *" << endl;
		cout << "*         6.排序算法性能分析                      *" << endl;
		cout << "*         0.退出系统                              *" << endl;
		cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
		cout << "请选择:" << endl;
		cin >> opt;
		switch (opt)
		{
		case 1:
			Read_File_Data(rr);
			break;
		case 2:
			if (mark1 == 0) {
				cout << "请先读取文件!" << endl;
				break;
			}
			Add_Record(rr);
			break;
		case 3:
			if (mark1 == 0) {
				cout << "请先读取文件!" << endl;
				break;
			}
			Sort(rr, sizecount);
			break;
		case 4:
			if (mark1 == 0 || mark2 == 0) {
				cout << "请先读取文件并排序!" << endl;
				break;
			}
			Search_Data(rr);
			break;
		case 5:
			if (mark1 == 0 || mark2 == 0) {
				cout << "请先读取文件并排序!" << endl;
				break;
			}
			Update(rr);
			break;
		case 6:
			Analysis();
			break;
		}
	}
	system("cls");
	cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                  已退出系统!                   *" << endl;
	cout << "*                 感谢您的使用!                  *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "*                                                 *" << endl;
	cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
}

int main()
{
	RoadRecord *dd = new RoadRecord[Length];//动态创建对象数组以防止stack overflow
	/*设计打开系统的简单欢迎界面*/
	cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
	for (int i = 0; i < 4; i++) {
		Sleep(500);
		cout << "*                                                 *" << endl;
	}
	Sleep(500);
	cout << "*                  系统加载中...                  *" << endl;
	Sleep(500);
	cout << "*                  请稍等:)                      *" << endl;
	for (int i = 0; i < 4; i++) {
		Sleep(500);
		cout << "*                                                 *" << endl;
	}
	Sleep(500);
	cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;
	Sleep(1000);
	system("cls");
	Menu(dd);
	delete[]dd;
	system("pause");
	return 0;
}

如有错误,欢迎指点

  • 12
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
学生成绩管理系统是一个比较常见的项目,主要涉及到学生信息、课程信息和成绩信息的管理。下面是C++实现学生成绩管理系统的基本思路。 1. 定义学生类 首先,需要定义一个学生类,包含学生的基本信息,如学号、姓名、性别等,以及一个成绩数组,用来存储学生的各门课程成绩。 ```c++ class Student { public: string id; //学号 string name; //姓名 string gender; //性别 float scores[3]; //成绩数组,存储三门课程的成绩 }; ``` 2. 定义课程类 接下来,需要定义一个课程类,包含课程的基本信息,如课程号、课程名称、学分等。 ```c++ class Course { public: string id; //课程号 string name; //课程名称 int credit; //学分 }; ``` 3. 定义成绩类 成绩类用来记录一个学生在一门课程中的成绩情况,包含学生的学号、课程号和成绩。 ```c++ class Score { public: string student_id; //学生学号 string course_id; //课程号 float score; //成绩 }; ``` 4. 定义学生信息管理类 学生信息管理类用来管理学生的基本信息,包括添加学生、删除学生、修改学生信息、查找学生信息等操作。 ```c++ class StudentManager { public: vector<Student> students; //学生数组,存储所有学生信息 //添加学生 void addStudent(Student s); //删除学生 void deleteStudent(string id); //修改学生信息 void modifyStudent(string id); //查找学生信息 Student findStudent(string id); //打印所有学生信息 void printAllStudents(); }; ``` 5. 定义课程信息管理类 课程信息管理类用来管理课程的基本信息,包括添加课程、删除课程、修改课程信息、查找课程信息等操作。 ```c++ class CourseManager { public: vector<Course> courses; //课程数组,存储所有课程信息 //添加课程 void addCourse(Course c); //删除课程 void deleteCourse(string id); //修改课程信息 void modifyCourse(string id); //查找课程信息 Course findCourse(string id); //打印所有课程信息 void printAllCourses(); }; ``` 6. 定义成绩信息管理类 成绩信息管理类用来管理学生的成绩信息,包括添加成绩、删除成绩、修改成绩、查找成绩等操作。 ```c++ class ScoreManager { public: vector<Score> scores; //成绩数组,存储所有成绩信息 //添加成绩 void addScore(Score s); //删除成绩 void deleteScore(string student_id, string course_id); //修改成绩 void modifyScore(string student_id, string course_id); //查找成绩 float findScore(string student_id, string course_id); //打印所有成绩信息 void printAllScores(); }; ``` 7. 实现主函数 在主函数中,需要实例化学生信息管理类、课程信息管理类和成绩信息管理类,然后通过菜单选择不同的操作。 ```c++ int main() { StudentManager sm; CourseManager cm; ScoreManager scm; int choice; while (true) { //打印菜单 cout << "1.添加学生\n2.删除学生\n3.修改学生信息\n4.查找学生信息\n5.打印所有学生信息\n" << "6.添加课程\n7.删除课程\n8.修改课程信息\n9.查找课程信息\n10.打印所有课程信息\n" << "11.添加成绩\n12.删除成绩\n13.修改成绩\n14.查找成绩\n15.打印所有成绩信息\n" << "16.退出\n"; cin >> choice; switch (choice) { case 1: //添加学生操作 break; case 2: //删除学生操作 break; case 3: //修改学生信息操作 break; case 4: //查找学生信息操作 break; case 5: //打印所有学生信息操作 break; case 6: //添加课程操作 break; case 7: //删除课程操作 break; case 8: //修改课程信息操作 break; case 9: //查找课程信息操作 break; case 10: //打印所有课程信息操作 break; case 11: //添加成绩操作 break; case 12: //删除成绩操作 break; case 13: //修改成绩操作 break; case 14: //查找成绩操作 break; case 15: //打印所有成绩信息操作 break; case 16: //退出程序 return 0; default: cout << "输入有误,请重新输入!\n"; break; } } return 0; } ``` 以上就是C++实现学生成绩管理系统的基本思路,具体的实现细节需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值