区号管理系统

缘由:受朋友之托帮忙开发,而后演变成一个自娱自乐的项目
不过能够一天开发出来并且push到github上也算是一种进步啦

项目:读取txt文件之后,输入省份 / 简称 / 城市 / 区号 / 邮政编码, 能输出全部对应数据
小花哨:使用map实现logn级别的相应

效果图:在这里插入图片描述

source code:

City.h:
#pragma once
#ifndef CITY_H_
#define CITY_H_
#include <string>

class city {

private:
	std::string province; // 省份
	std::string abbreviation; // 简称
	std::string cityName; // 城市名称
	int zoneDiscription; // 区号
	int postalCode; // 邮政编码

public:
	// 对类进行初始化
	city();
	city(std::string &p, std::string &a, std::string &c, int &z, int &po) : 
		province(p), abbreviation(a), cityName(c), zoneDiscription(z), postalCode(po) {}

	// 相应类成员的构造函数
	void setProvince(std::string & p);
	void setAbbreviation(std::string & a);
	void setCityName(std::string & c);
	void setZoneDiscription(int & z);
	void setPostalCode(int & po);

	// 为了达到数据封装目的,提供接口函数实现对类成员的访问
	std::string getProvince();
	std::string getAbbreviation();
	std::string getCityName();
	int getZoneDiscription();
	int getPostalCode();
};
#endif




City.cpp:
#pragma once
#ifndef CITY_CPP_
#define CITY_CPP_
#include "City.h"

city::city() {
	province = abbreviation = cityName = " ";
	zoneDiscription = postalCode = 0;
}

// 初始化类成员
void city::setProvince(std::string& p) { province = p; }
void city::setAbbreviation(std::string& a) { abbreviation = a; }
void city::setCityName(std::string& c) { cityName = c; }
void city::setZoneDiscription(int& z) { zoneDiscription = z; }
void city::setPostalCode(int& po) { postalCode = po; }

std::string city::getProvince() { return province; }
std::string city::getAbbreviation() { return abbreviation; }
std::string city::getCityName() { return cityName; }

int city::getZoneDiscription() { return zoneDiscription; }
int city::getPostalCode() { return postalCode; }

#endif 






Load.cpp:
#pragma once
#ifndef LOAD_H_
#define LOAD_H_
#include <iostream>
#include <fstream>
#include <map>
using namespace std;

extern city* allCity = nullptr;

map<std::string, int> corProvince;
map<std::string, int> corAbbreviation;
map<std::string, int> corCityName;
map<int, int> corZoneDiscription;
map<int, int> corPostalCode;

// 功能:提取字符串中的数字
// 参数:字符串
// 返回:int类型数字
int transNum(string& s) {
	// 例:"区号:01"
	// 第一步实现数字部分的截断,即提取ASCii码形式的01
	// 第二步再将ASCii码形式的数字01转换为int类型的数字01
	
	// 第一步利用字符串的substr()函数对字符串进行截断
	// 由于中英文字符不同的缘故,所以截取时长度要+ 2
	string temp;
	size_t pos = s.find(":");    
	temp = s.substr(pos + 2);     

	// 第二步对每个字符进行处理转换为数字形式
	int ans = 0; 
	int sub = 0; // 标记temp的下标
	int digit = 0; // 标记每个字符转化为数字的形式
	while (sub + 1 <= temp.length()) {
		digit = temp[sub++] - '0';
		ans = ans * 10 + digit;
	}
	return ans;
}

// 功能:提取字符串中所需要的有用字符
// 参数:字符串
// 返回:字符串
string transString(string& s) {
	string temp = " ";	string ans = " ";
	size_t pos = s.find(":");
	temp = s.substr(pos + 2);
	return temp;
}

// 功能:统计文本的行数
// 参数:ifstream对象
// 返回:文本行数
int lineCount(ifstream& temp) {
	char c;
	int count = 0;
	while (temp.get(c)) {
		if (c == '\n')
			count++;
	}
	return count + 1; // txt文件最后一行没有'\n',所以统计时要+ 1
}

// 功能:将文本数据存储到allCity类指针所指向的内存
// 参数:ifstream对象
// 返回:void
void readData(ifstream& temp) {
	// 获取文本行数并分配内存
	int totalLines = lineCount(temp);
	allCity = new city[totalLines];

	temp.clear(); // 由于统计了行数,使文件指针指向了文件末尾,首先清除文件流状态
	temp.seekg(0, ios::beg); // 其次回到文件的起始位置

	// 逐步读取数据并存储
	std::string s = " ";	int occa = 0;	int sub = 0;
	while (!temp.eof()) {
		// EOF是一个宏,它代表了-1这个值,如果在文件当中读到了0xff或者到了文件末尾,
		// 文件结构指针里面的flags字节的_F_EOF位都会被置为1,这一位被置为1,库函数就会认为到了文件末尾了。
		// 函数feof()其实是一个类函数宏,这个宏就是通过把文件结构指针的flags字节跟_F_EOF进行与运算来检测_F_EOF是否为1,并判断是否到了文件末尾的。
		temp >> s;	s = transString(s);  corProvince[s] = sub;      allCity[sub].setProvince(s);
		temp >> s;	s = transString(s);  corAbbreviation[s] = sub;  allCity[sub].setAbbreviation(s);
		temp >> s;	s = transString(s);  corCityName[s] = sub;      allCity[sub].setCityName(s);

		// 提取字符串中的数字并进行存储
		temp >> s;	occa = transNum(s);  corZoneDiscription[occa] = sub;  allCity[sub].setZoneDiscription(occa);
		temp >> s;	occa = transNum(s);  corPostalCode[occa] = sub;       allCity[sub].setPostalCode(occa);
		sub++;
	}
}

// 功能:实现对以txt形式存储的文件,读取文本数据并存储
// 参数:void
// 返回:void
void loadTxt() {
	ifstream fin;

	// 对文件是否成功打开进行判断
	fin.open("D:/Temp.txt", ios::in);
	if (!fin) {
		cerr << "Error : fail to open the file." << endl;
		exit(1);
	}

	readData(fin);
	fin.close();
}

#endif





Test.cpp:
#include "City.h"
#include "Load.cpp" // 实现对txt文件的读取
#include <iostream>
using namespace std;

void searchInterface();

void Init() {
	// 注意:map不能成为city本身的数据成员,否则形成会对自身的循环调用
	corProvince.clear();
	corAbbreviation.clear();
	corCityName.clear();
	corZoneDiscription.clear();
	corPostalCode.clear();
}

int main() {
	Init(); // Init()与loadTxt()的先后顺序是重要的,否则所有的map映射都只能映射到第一条数据
	loadTxt();
	searchInterface();
	return 0;
}

void print(int sub) {
	cout << endl;
	cout << "省份:\t" << allCity[sub].getProvince() << endl
		<< "简称:\t" << allCity[sub].getAbbreviation() << endl
		<< "城市:\t" << allCity[sub].getCityName() << endl
		<< "区号:\t" << allCity[sub].getZoneDiscription() << endl
		<< "邮政编码:\t" << allCity[sub].getPostalCode() << endl;
	return;
}

// 交互界面的设计
void searchInterface() {
	cout << "Welcome to search system!" << endl
		<< "Dear user, you can choose and input one way to search the information you need." << endl
		<< "1.\tSearch by province." << endl
		<< "2.\tSearch by abbreviation." << endl
		<< "3.\tSearch by city" << endl
		<< "4.\tSearch by zone discription." << endl
		<< "5.\tSearch by postal code." << endl
		<< "$ ";

	string s;	
	while (1) {
		getline(cin, s);	cout << endl;
		if (s == "Search by province") { 
			cout << "Please input the province:" << endl
				<< "$ ";
			string province;	getline(cin, province);
			print(corProvince[province]);  
			break; 
		}
		if (s == "Search by abbreviation") {
			cout << "Please input the abbreviation:" << endl
				<< "$ ";
			string abbreviation;	getline(cin, abbreviation);
			print(corAbbreviation[abbreviation]);
			break;
		}
		if (s == "Search by city") {
			cout << "Please input the city:" << endl
				<< "$ ";
			string city;	getline(cin, city);
			print(corCityName[city]);
			break;
		}
		if (s == "Search by zone discription") {
			cout << "Please input the zone discription:" << endl
				<< "$ ";
			int zoneDiscription;	cin >> zoneDiscription;
			print(corZoneDiscription[zoneDiscription]);
			break;
		}
		if (s == "Search by postal code") {
			cout << "Please input the postal code:" << endl
				<< "$ ";
			int postalCode;		cin >> postalCode;
			print(corPostalCode[postalCode]);
			break;
		}

		// 如果输入了均不符合的语句,那么抛出异常并重新输入
		if (s != "Search by province" &&
			s != "Search by abbreviation" &&
			s != "Search by city" &&
			s != "Search by zone discription" &&
			s != "Search by postal code") {
				cerr << "Error : Fail to search. Please input again.";
				cout << endl << "$ ";
		}
			
	}
	return;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值