introduction
The data structure course design at the end of this semester requires us to complete a simple small program. I chose a ticket sales system to realize some basic functions; Because the time is short and I make up lessons in the review week, there is nothing outstanding. I'll talk about my code implementation and what can be further improved here;
Note: the program does not use the object-oriented part of C + +, but uses process oriented programming, mainly using some containers and functions of C + +;
Implementation process
basic function
The functions are simple, including the following five types:
1. Ticket purchase
2. Refund
3. Display user information
4. Query user information
5. View flight information
Because it is a ticketing system, operations such as adding and deleting flights are not added. Of course, it is easy to add if you want to;
Although the function is very simple, the judgment of input information needs to be rigorous, so how to formulate judgment rules also needs to be considered;
data structure
Firstly, we consider what data structure is used to store user information and flight information. Because we need to quickly retrieve information and use the most basic file operation instead of database, we consider using hash table to store user information and flight information, and set the key value to the last six digits of ID card and flight number respectively; (here, the hash table operation is implemented through the map container)
structural morphology
Then consider the structure of users and flights, and the code is as follows:
// Customer information structure struct Person { string name; // full name string age; // Age string gender; // Gender string idNum; // ID number string myAirNum; // User flight number }; // Flight information structure struct Airplane { string airNum; // flight number string startPoint; // starting point string destination; // destination string tickets; // Number of votes string ticketPrice; // Ticket Price string departureTime; // Takeoff time };
It's very simple and there's nothing to say. Someone may find: why do all variables use string type? It is mainly considered that the contents of the file should be read into the memory during initialization, and all the strings read from the file are strings, so they are directly defined as strings;
Of course, this is not necessarily the best way. I also thought of defining a set of transformation system, but time is tight, so I don't tangle too much here; If you have a better way, you are also welcome to communicate!
file
Because I use files instead of databases here, I don't need to consider the design of table structure, but I still need to design the basic file format;
First, select two documents txt file, one is userInfo to store user information, and the other is airport to store flight information;
Next, we need to consider how to store the file. Because the initialization needs to read the contents of the file into memory, I define that each user information (flight information) occupies one line, and each attribute is divided by a space. In this way, when reading the file, you can read only one line at a time, and then divide the string based on the space;
The contents of the document are shown in the figure below:
function
Now you can think about what functions you need. I divide functions into two categories: basic function functions and tool functions;
The function comments have been very detailed. Unless I will elaborate on special ones, I won't say much about others;
1, Basic function
Function declaration:
void initInfo(); // Initialization information void UI(); // UI interface void showUserInfo(); // Display output user information void showAirplaneInfo(); // Display and output flight information void sellTickets(); // sell ticket void selectUserInfo(string idNum); // Query user information void refundTickets(string idNum); // to refund a ticket
UI interface
Print out the operation interface and operation summary;
/// <summary> ///UI interface /// </summary> void UI() { while (true) { // Print interface cout << "************Welcome xxxx Air ticketing system**********" << endl; cout << "************** 1, purchase ticket **************" << endl; cout << "************** 2, retreat ticket **************" << endl; cout << "************** 3,View ticket information **************" << endl; cout << "************** 4,Find user information **************" << endl; cout << "************** 5,View flight information **************" << endl; cout << "************** 6, retreat Out **************" << endl; int choose; // option cin >> choose; // Input selection switch (choose) { case 1 : sellTickets(); // sell ticket break; case 2: { string id; while (true) { cout << "Please input the ID number of the refund person:"; cin >> id; // Judge whether the ID number is legal. if (idNumIsLegal(id)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } refundTickets(id); // to refund a ticket break; } case 3 : showUserInfo(); // View ticket information break; case 4: { string id; while (true) { cout << "Please enter the ID number for the user:"; cin >> id; // Judge whether the ID number is legal. if (idNumIsLegal(id)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } selectUserInfo(id); // View query user information break; } case 5 : showAirplaneInfo(); // View flight information break; case 6 : cout << "Welcome to use next time!" << endl; exit(-1); // sign out } system("pause"); system("cls"); } }
Initialization information
The main purpose is to initialize the contents of the file into memory to facilitate subsequent operations;
/// <summary> ///Initialization information /// </summary> void initInfo() { ifstream ifs01; // Initialize flight information ifs01.open("airplane.txt", ios::in); // Open file // If file opening fails if (!ifs01.is_open()) { cout << "File opening failed!\a" << endl; exit(-1); } // If the flight information is not empty string ainfo; // Temporarily store each flight information // Read customer information by line while (getline(ifs01, ainfo)) { vector<string> separateInfo; // Store separate information separateInfo = split(ainfo, " "); // Separate flight information Airplane airplane; // Store temporary flight information airplane.airNum = separateInfo[0]; // Deposit flight number airplane.startPoint = separateInfo[1]; // Storage starting point airplane.destination = separateInfo[2]; // Storage destination airplane.tickets = separateInfo[3]; // Number of votes deposited airplane.ticketPrice = separateInfo[4]; // Deposit fare airplane.departureTime = separateInfo[5]; // Store takeoff time // Flight information storage string key = separateInfo[0]; // Get the key value, i.e. flight number airplaneInfo.insert(pair<string, Airplane>(key, airplane)); // Save flight information into map } ifs01.close(); // Initialize user information ifstream ifs02; ifs02.open("userInfo.txt", ios::in); // Open file // If file opening fails if (!ifs02.is_open()) { cout << "File opening failed!\a" << endl; exit(-1); } // If user information is not empty string info; // Temporarily store each customer information // Read customer information by line while (getline(ifs02, info)) { vector<string> separateInfo; // Store separate information separateInfo = split(info, " "); // Separate customer information Person person; // Store temporary customer information person.name = separateInfo[0]; // Deposit name person.age = separateInfo[1]; // Storage age person.gender = separateInfo[2]; // Storage gender person.idNum = separateInfo[3]; // Storage ID number person.myAirNum = separateInfo[4]; // Deposit flight number // Customer information storage string key = separateInfo[3].substr(13); // The last six digits of the ID card are the map index value key userInfo.insert(pair<string, Person>(key, person)); // Store customer information in map } ifs02.close(); }
sell ticket
Add users and save files;
/// <summary> ///Ticket selling /// </summary> void sellTickets() { // 1. Enter user information Person person; // Ticket customer // Enter name while (true) { cout << "Please enter your name:"; cin >> person.name; // Judge whether the name is legal if (nameIsLegal(person.name)) { break; } cout << "The name is illegal, please re-enter!" << endl; } // Enter age while (true) { cout << "Please enter age:"; cin >> person.age; // Judge whether the input age is in line with common sense if (stringToInt(person.age) > 110 || stringToInt(person.age) < 0) { cout << "Illegal age, please re-enter!" << endl; } else { break; } } // Enter gender while (true) { cout << "Please enter gender:"; cin >> person.gender; // Judge whether the input gender is legal if (person.gender == "male" || person.gender == "female") { break; } cout << "Illegal gender, please re-enter!" << endl; } // Enter ID number while (true) { cout << "Please enter your ID number:"; cin >> person.idNum; // Judge whether the ID number is legal. if (idNumIsLegal(person.idNum)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } // Enter flight number while (true) { cout << "Please enter flight number:"; cin >> person.myAirNum; // Judge whether the flight number is legal, the flight exists and the number of people is not full if (person.myAirNum[0] == 'x' && person.myAirNum.length() == 4 && airplaneInfo.find(person.myAirNum) != airplaneInfo.end() && stringToInt(airplaneInfo[person.myAirNum].tickets) != 0) { // If the current flight is purchased, the number of tickets for the flight should be reduced by one int tickets = stringToInt(airplaneInfo[person.myAirNum].tickets); // Convert to shaping tickets--; // The number of votes is reduced by one airplaneInfo[person.myAirNum].tickets = to_string(tickets); // Convert to string updateAirplaneFile(); // Update flight file break; } cout << "The flight number is illegal or does not exist or the number of flights is full, please select again!" << endl; } // 2. User information is stored in userInfo string key = person.idNum.substr(13); // Get the corresponding key value of the user: the ID number is 6 bits. userInfo.insert(pair<string, Person>(key, person)); // Store user information in map // 3. Write new user information to file fstream fs; fs.open("userInfo.txt", ios::out | ios::app); // Open file // write file fs << person.name + " " << person.age + " " << person.gender + " " << person.idNum + " " << person.myAirNum + " " << endl; cout << "Ticket purchase succeeded!!" << endl; fs.close(); }
Display output user information
/// <summary> ///Display output user information /// </summary> void showUserInfo() { // Judge whether the user information is empty if (userInfo.empty()) { cout << "User information is empty!!" << endl; return; } // If the user information is not empty, start traversal map<string, Person>::iterator it; // iterator for (it = userInfo.begin(); it != userInfo.end(); it++) { cout << "full name:" + it->second.name << " Age:" + it->second.age << " Gender:" + it->second.gender << " ID number:" + it->second.idNum << " flight number:" + it->second.myAirNum << " starting point:" + airplaneInfo[it->second.myAirNum].startPoint << " End:" + airplaneInfo[it->second.myAirNum].destination << " Ticket Price:" + airplaneInfo[it->second.myAirNum].ticketPrice << " Departure time:" + airplaneInfo[it->second.myAirNum].departureTime << endl; } }
Display and output flight information
/// <summary> ///Display and output flight information /// </summary> void showAirplaneInfo() { // If flight information is empty if (airplaneInfo.empty()) { cout << "Flight information is empty!" << endl; return; } // If the flight information is not empty, start traversal map<string, Airplane>::iterator it; // iterator int i = 0; for (it = airplaneInfo.begin(); it != airplaneInfo.end(); it++) { cout << "flight number:" + it->second.airNum << " starting point:" + it->second.startPoint << " End:" + it->second.destination << " Number of votes:" + it->second.tickets << " Ticket Price:" + it->second.ticketPrice << " Departure time:" + it->second.departureTime << endl; } }
Query user information
Just find it directly;
/// <summary> ///Query user information /// </summary> /// <param name= "idNum" > query user ID number </param> void selectUserInfo(string idNum) { string key = idNum.substr(13); // Get key value: ID number 6 after 6. // Judge whether the user information exists if (userInfo.find(key) == userInfo.end()) { cout <<"The user does not exist!!" << endl; return ; } Person person = userInfo[key]; // Find user information through key // Output user information cout << "full name:" + person.name << " Age:" + person.age << " Gender:" + person.gender << " ID number:" + person.idNum << " flight number:" + person.myAirNum << " starting point:" + airplaneInfo[person.myAirNum].startPoint << " End:" + airplaneInfo[person.myAirNum].destination << " Ticket Price:" + airplaneInfo[person.myAirNum].ticketPrice << " Departure time:" + airplaneInfo[person.myAirNum].departureTime << endl; }
to refund a ticket
For ticket refund, not only the user information should be deleted in the memory, but also in the file; However, the file operation does not have the function of direct deletion, so when the user information in the memory is deleted, clear all the file information, and then rewrite it, and write the user information in the memory into the file;
/// <summary> ///Refund /// </summary> //<param name= "idNum" > refund ticket user ID number </param> void refundTickets(string idNum) { // Determine whether the user exists string key = idNum.substr(13); // If it doesn't exist if (userInfo.find(key) == userInfo.end()) { cout << "User information does not exist!" << endl; return; } // If yes, the number of tickets for this flight needs to be increased by one int tickets = stringToInt(airplaneInfo[userInfo[key].myAirNum].tickets); // String to integer tickets++; // Number of votes plus one airplaneInfo[userInfo[key].myAirNum].tickets = to_string(tickets); // Integer to string updateAirplaneFile(); // Update flight file userInfo.erase(key); // Delete from user information // Delete the user information from the file clearFile("userInfo.txt"); // Empty file // Rewrite file fstream fs; fs.open("userInfo.txt", ios::out | ios::app); // Open file // Traverse and rewrite user information for (auto i : userInfo) { fs << i.second.name + " " << i.second.age + " " << i.second.gender + " " << i.second.idNum + " " << i.second.myAirNum << endl; } fs.close(); cout << "Refund succeeded!!" << endl; }
2, Tool function
Function declaration:
vector<string> split(const string& str, const string& delim); // String segmentation function bool idNumIsLegal(string idNum); // Judge whether the ID number is legal. bool nameIsLegal(string name); // Judge whether the name is legal int stringToInt(string str); // Convert string type to int type void clearFile(const string fileName); // Empty file contents void updateAirplaneFile(); // Update flight file information
String segmentation function
Because there is no split function in C + +, but the corresponding functions can be realized through the strtok function of C language, I encapsulated a string segmentation function myself;
/// <summary> ///String segmentation function /// </summary> ///< param name = "STR" > required split string < / param > ///< param name = "delim" > segmentation criteria < / param > ///< returns > string array < / returns > vector<string> split(const string& str, const string& delim) { vector<string> res; // An array that holds split strings if ("" == str) return res; // If the string is empty, it cannot be split // First convert the string to be cut from string type to char * type char* strs = new char[str.length() + 1]; strcpy(strs, str.c_str()); char* d = new char[delim.length() + 1]; strcpy(d, delim.c_str()); // Convert delim to char * and assign it to d char* p = strtok(strs, d); // The first call points to the decomposition string while (p) { string s = p; // The split string is converted to string type res.push_back(s); // Save to result array p = strtok(NULL, d); // After each segmentation, the decomposition string is NULL } return res; }
Judge whether the ID number is legal.
In fact, the identification of ID number is only required to separate the ID number into several parts, and separately judge it.
But it's a bit cumbersome. You can choose a simpler regular expression to achieve judgement. Just C++ supports regular expressions, so I found the regular expression of the ID number on the Internet directly.
/// <summary> //Judge whether the ID number is legal. /// </summary> /// <param name= "idNum" > ID number </param> ///< returns > legal is true, illegal is false < / returns > bool idNumIsLegal(string idNum) { // Define a regular expression Rule of 18 digit ID number regex repPattern("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"); // Declare matching result variables match_results<string::const_iterator> rerResult; // Match bool bValid = regex_match(idNum, rerResult, repPattern); if (bValid) { // Match successful //Cout "ID number format is legal!" endl; return true; } //Cout "the format of ID number is not legal!" endl; return false; }
Judge whether the name is legal
Just like the ID number judgement, regular expression is used directly.
/// <summary> ///Judge whether the name is legal /// </summary> ///< param name = "name" > name < / param > ///< returns > legal is true, illegal is false < / returns > bool nameIsLegal(string name) { // Define a regular expression Rule of 18 digit ID number regex repPattern("^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$"); // Declare matching result variables match_results<string::const_iterator> rerResult; // Match bool bValid = regex_match(name, rerResult, repPattern); if (bValid) { // Match successful //Cout < < "the name format is legal!"<< endl; return true; } //Cout < < "illegal name format!"<< endl; return false; }
Convert string type to int type
This uses the stoi function. For those who don't understand it, please see my article: stoi(), atoi(), to in C + +_ String () tips
/// <summary> ///Convert string type to int type /// </summary> ///< param name = "STR" > string to be converted < / param > ///< returns > the converted integer of the string < / returns > int stringToInt(string str) { // Determine whether the string is empty if (str.empty()) { cout << "Data error, please check the file data!" << endl; return 0; } return stoi(str); // Convert string to integer }
Empty file contents
/// <summary> ///Empty file contents /// </summary> ///< param name = "filename" > file name < / param > void clearFile(const string fileName) { fstream file(fileName, ios::out); }
Update flight file information
This is the same as updating user information, that is, the rewriting is deleted, because it is written into a function separately after being used for many times;
/// <summary> ///Update flight file information /// </summary> void updateAirplaneFile() { // Remove from file clearFile("airplane.txt"); // Empty file // Rewrite file fstream fs; fs.open("airplane.txt", ios::out | ios::app); // Open file // Traverse and re write flight information for (auto i : airplaneInfo) { fs << i.second.airNum + " " << i.second.startPoint + " " << i.second.destination + " " << i.second.tickets + " " << i.second.ticketPrice + " " << i.second.departureTime + " " << endl; } fs.close(); }
summary
Because the function implementation of this project is very simple, the code implementation is not so difficult; In fact, I think the most difficult thing at the beginning of a project is the process from 0 to 1. When the whole framework is established, there is actually no difficulty;
shortcoming
In fact, there is still a problem in the design of user information. If we get the ID number, we can get the gender and age of users directly. These two variables are redundant. If the code is further improved, I will give priority to this. This is also a problem in the initial design. It was only thought of in the end. At this time, if it was modified, there would be a lot of modified contents;
For me, this is also a lesson. The initial design must be rigorous, so as to avoid large-scale modification in the later stage;
At present, I haven't thought of any other problems. If you have other discoveries or novel ideas, you are welcome to communicate;
Code network disk link
Here is a link to obtain code and files. The software I use is vs2019. Some old gcc versions may not recognize regular expressions, so you can update the gcc version or use vs2019, that is, the above version;
Baidu online disk:
Link: https://pan.baidu.com/s/1BkLI-FhpJ05O2sTMUuf6cw
Extraction code: xxxx
Complete code
/* Project Name: ticket sales system Basic function realization: 1,Ticket purchase 2,to refund a ticket 3,Display user information 4,Query user information 5,View flight information Author:********** Version: 1.2 Date: December 23, 2021 Compilation environment: Visual Studio 2019, C++11 Note: vs2019 or above is recommended. Regular expressions may not be recognized if the gcc version is too low You need to manually configure the latest gcc version */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstring> #include<string.h> #include<vector> #include<map> #include<regex> #include<fstream> #include<Windows.h> using namespace std; // // structural morphology // // Customer information structure struct Person { string name; // full name string age; // Age string gender; // Gender string idNum; // ID number //string destination; // destination //vector<Airplane> airplane; // Tickets purchased string myAirNum; // User flight number }; // Flight information structure struct Airplane { string airNum; // flight number string startPoint; // starting point string destination; // destination string tickets; // Number of votes string ticketPrice; // Ticket Price string departureTime; // Takeoff time }; // // global variable // map<string, Person> userInfo; // Global variable to store user information map<string, Airplane> airplaneInfo; // Global variable to store flight information // // Function declaration // void initInfo(); // Initialization information void UI(); // UI interface void showUserInfo(); // Display output user information void showAirplaneInfo(); // Display and output flight information void sellTickets(); // sell ticket void selectUserInfo(string idNum); // Query user information void refundTickets(string idNum); // to refund a ticket vector<string> split(const string& str, const string& delim); // String segmentation function bool idNumIsLegal(string idNum); // Judge whether the ID number is legal. bool nameIsLegal(string name); // Judge whether the name is legal int stringToInt(string str); // Convert string type to int type void clearFile(const string fileName); // Empty file contents void updateAirplaneFile(); // Update flight file information // Airplane stringToAirplane(string info); // Convert string to airplane type // // main function // int main() { initInfo(); UI(); return 0; } // // Function implementation // /// <summary> ///UI interface /// </summary> void UI() { while (true) { // Print interface cout << "************Welcome xxxx Air ticketing system**********" << endl; cout << "************** 1, purchase ticket **************" << endl; cout << "************** 2, retreat ticket **************" << endl; cout << "************** 3,View ticket information **************" << endl; cout << "************** 4,Find user information **************" << endl; cout << "************** 5,View flight information **************" << endl; cout << "************** 6, retreat Out **************" << endl; int choose; // option cin >> choose; // Input selection switch (choose) { case 1 : sellTickets(); // sell ticket break; case 2: { string id; while (true) { cout << "Please input the ID number of the refund person:"; cin >> id; // Judge whether the ID number is legal. if (idNumIsLegal(id)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } refundTickets(id); // to refund a ticket break; } case 3 : showUserInfo(); // View ticket information break; case 4: { string id; while (true) { cout << "Please enter the ID number for the user:"; cin >> id; // Judge whether the ID number is legal. if (idNumIsLegal(id)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } selectUserInfo(id); // View query user information break; } case 5 : showAirplaneInfo(); // View flight information break; case 6 : cout << "Welcome to use next time!" << endl; exit(-1); // sign out } system("pause"); system("cls"); } } /// <summary> ///Initialization information /// </summary> void initInfo() { ifstream ifs01; // Initialize flight information ifs01.open("airplane.txt", ios::in); // Open file // If file opening fails if (!ifs01.is_open()) { cout << "File opening failed!\a" << endl; exit(-1); } // If the flight information is not empty string ainfo; // Temporarily store each flight information // Read customer information by line while (getline(ifs01, ainfo)) { vector<string> separateInfo; // Store separate information separateInfo = split(ainfo, " "); // Separate flight information Airplane airplane; // Store temporary flight information airplane.airNum = separateInfo[0]; // Deposit flight number airplane.startPoint = separateInfo[1]; // Storage starting point airplane.destination = separateInfo[2]; // Storage destination airplane.tickets = separateInfo[3]; // Number of votes deposited airplane.ticketPrice = separateInfo[4]; // Deposit fare airplane.departureTime = separateInfo[5]; // Store takeoff time // Flight information storage string key = separateInfo[0]; // Get the key value, i.e. flight number airplaneInfo.insert(pair<string, Airplane>(key, airplane)); // Save flight information into map } ifs01.close(); // Initialize user information ifstream ifs02; ifs02.open("userInfo.txt", ios::in); // Open file // If file opening fails if (!ifs02.is_open()) { cout << "File opening failed!\a" << endl; exit(-1); } // If user information is not empty string info; // Temporarily store each customer information // Read customer information by line while (getline(ifs02, info)) { vector<string> separateInfo; // Store separate information separateInfo = split(info, " "); // Separate customer information Person person; // Store temporary customer information person.name = separateInfo[0]; // Deposit name person.age = separateInfo[1]; // Storage age person.gender = separateInfo[2]; // Storage gender person.idNum = separateInfo[3]; // Storage ID number person.myAirNum = separateInfo[4]; // Deposit flight number // Customer information storage string key = separateInfo[3].substr(13); // The last six digits of the ID card are the map index value key userInfo.insert(pair<string, Person>(key, person)); // Store customer information in map } ifs02.close(); } /// <summary> ///Ticket selling /// </summary> void sellTickets() { // 1. Enter user information Person person; // Ticket customer // Enter name while (true) { cout << "Please enter your name:"; cin >> person.name; // Judge whether the name is legal if (nameIsLegal(person.name)) { break; } cout << "The name is illegal, please re-enter!" << endl; } // Enter age while (true) { cout << "Please enter age:"; cin >> person.age; // Judge whether the input age is in line with common sense if (stringToInt(person.age) > 110 || stringToInt(person.age) < 0) { cout << "Illegal age, please re-enter!" << endl; } else { break; } } // Enter gender while (true) { cout << "Please enter gender:"; cin >> person.gender; // Judge whether the input gender is legal if (person.gender == "male" || person.gender == "female") { break; } cout << "Illegal gender, please re-enter!" << endl; } // Enter ID number while (true) { cout << "Please enter your ID number:"; cin >> person.idNum; // Judge whether the ID number is legal. if (idNumIsLegal(person.idNum)) { break; } cout << "The ID number is not valid. Please retype it." << endl; } // Enter flight number while (true) { cout << "Please enter flight number:"; cin >> person.myAirNum; // Judge whether the flight number is legal, the flight exists and the number of people is not full if (person.myAirNum[0] == 'x' && person.myAirNum.length() == 4 && airplaneInfo.find(person.myAirNum) != airplaneInfo.end() && stringToInt(airplaneInfo[person.myAirNum].tickets) != 0) { // If the current flight is purchased, the number of tickets for the flight should be reduced by one int tickets = stringToInt(airplaneInfo[person.myAirNum].tickets); // Convert to shaping tickets--; // The number of votes is reduced by one airplaneInfo[person.myAirNum].tickets = to_string(tickets); // Convert to string updateAirplaneFile(); // Update flight file break; } cout << "The flight number is illegal or does not exist or the number of flights is full, please select again!" << endl; } // 2. User information is stored in userInfo string key = person.idNum.substr(13); // Get the corresponding key value of the user: the ID number is 6 bits. userInfo.insert(pair<string, Person>(key, person)); // Store user information in map // 3. Write new user information to file fstream fs; fs.open("userInfo.txt", ios::out | ios::app); // Open file // write file fs << person.name + " " << person.age + " " << person.gender + " " << person.idNum + " " << person.myAirNum + " " << endl; cout << "Ticket purchase succeeded!!" << endl; fs.close(); } /// <summary> ///Display output user information /// </summary> void showUserInfo() { // Judge whether the user information is empty if (userInfo.empty()) { cout << "User information is empty!!" << endl; return; } // If the user information is not empty, start traversal map<string, Person>::iterator it; // iterator for (it = userInfo.begin(); it != userInfo.end(); it++) { cout << "full name:" + it->second.name << " Age:" + it->second.age << " Gender:" + it->second.gender << " ID number:" + it->second.idNum << " flight number:" + it->second.myAirNum << " starting point:" + airplaneInfo[it->second.myAirNum].startPoint << " End:" + airplaneInfo[it->second.myAirNum].destination << " Ticket Price:" + airplaneInfo[it->second.myAirNum].ticketPrice << " Departure time:" + airplaneInfo[it->second.myAirNum].departureTime << endl; } } /// <summary> ///Display and output flight information /// </summary> void showAirplaneInfo() { // If flight information is empty if (airplaneInfo.empty()) { cout << "Flight information is empty!" << endl; return; } // If the flight information is not empty, start traversal map<string, Airplane>::iterator it; // iterator int i = 0; for (it = airplaneInfo.begin(); it != airplaneInfo.end(); it++) { cout << "flight number:" + it->second.airNum << " starting point:" + it->second.startPoint << " End:" + it->second.destination << " Number of votes:" + it->second.tickets << " Ticket Price:" + it->second.ticketPrice << " Departure time:" + it->second.departureTime << endl; } } /// <summary> ///Query user information /// </summary> /// <param name= "idNum" > query user ID number </param> void selectUserInfo(string idNum) { string key = idNum.substr(13); // Get key value: ID number 6 after 6. // Judge whether the user information exists if (userInfo.find(key) == userInfo.end()) { cout <<"The user does not exist!!" << endl; return ; } Person person = userInfo[key]; // Find user information through key // Output user information cout << "full name:" + person.name << " Age:" + person.age << " Gender:" + person.gender << " ID number:" + person.idNum << " flight number:" + person.myAirNum << " starting point:" + airplaneInfo[person.myAirNum].startPoint << " End:" + airplaneInfo[person.myAirNum].destination << " Ticket Price:" + airplaneInfo[person.myAirNum].ticketPrice << " Departure time:" + airplaneInfo[person.myAirNum].departureTime << endl; } /// <summary> ///Refund /// </summary> //<param name= "idNum" > refund ticket user ID number </param> void refundTickets(string idNum) { // Determine whether the user exists string key = idNum.substr(13); // If it doesn't exist if (userInfo.find(key) == userInfo.end()) { cout << "User information does not exist!" << endl; return; } // If yes, the number of tickets for this flight needs to be increased by one int tickets = stringToInt(airplaneInfo[userInfo[key].myAirNum].tickets); // String to integer tickets++; // Number of votes plus one airplaneInfo[userInfo[key].myAirNum].tickets = to_string(tickets); // Integer to string updateAirplaneFile(); // Update flight file userInfo.erase(key); // Delete from user information // Delete the user information from the file clearFile("userInfo.txt"); // Empty file // Rewrite file fstream fs; fs.open("userInfo.txt", ios::out | ios::app); // Open file // Traverse and rewrite user information for (auto i : userInfo) { fs << i.second.name + " " << i.second.age + " " << i.second.gender + " " << i.second.idNum + " " << i.second.myAirNum << endl; } fs.close(); cout << "Refund succeeded!!" << endl; } /// <summary> ///Update flight file information /// </summary> void updateAirplaneFile() { // Remove from file clearFile("airplane.txt"); // Empty file // Rewrite file fstream fs; fs.open("airplane.txt", ios::out | ios::app); // Open file // Traverse and re write flight information for (auto i : airplaneInfo) { fs << i.second.airNum + " " << i.second.startPoint + " " << i.second.destination + " " << i.second.tickets + " " << i.second.ticketPrice + " " << i.second.departureTime + " " << endl; } fs.close(); } /// <summary> ///String segmentation function /// </summary> ///< param name = "STR" > required split string < / param > ///< param name = "delim" > segmentation criteria < / param > ///< returns > string array < / returns > vector<string> split(const string& str, const string& delim) { vector<string> res; // An array that holds split strings if ("" == str) return res; // If the string is empty, it cannot be split // First convert the string to be cut from string type to char * type char* strs = new char[str.length() + 1]; strcpy(strs, str.c_str()); char* d = new char[delim.length() + 1]; strcpy(d, delim.c_str()); // Convert delim to char * and assign it to d char* p = strtok(strs, d); // The first call points to the decomposition string while (p) { string s = p; // The split string is converted to string type res.push_back(s); // Save to result array p = strtok(NULL, d); // After each segmentation, the decomposition string is NULL } return res; } /// <summary> //Judge whether the ID number is legal. /// </summary> /// <param name= "idNum" > ID number </param> ///< returns > legal is true, illegal is false < / returns > bool idNumIsLegal(string idNum) { // Define a regular expression Rule of 18 digit ID number regex repPattern("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"); // Declare matching result variables match_results<string::const_iterator> rerResult; // Match bool bValid = regex_match(idNum, rerResult, repPattern); if (bValid) { // Match successful //Cout "ID number format is legal!" endl; return true; } //Cout "the format of ID number is not legal!" endl; return false; } /// <summary> ///Judge whether the name is legal /// </summary> ///< param name = "name" > name < / param > ///< returns > legal is true, illegal is false < / returns > bool nameIsLegal(string name) { // Define a regular expression Rule of 18 digit ID number regex repPattern("^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$"); // Declare matching result variables match_results<string::const_iterator> rerResult; // Match bool bValid = regex_match(name, rerResult, repPattern); if (bValid) { // Match successful //Cout < < "the name format is legal!"<< endl; return true; } //Cout < < "illegal name format!"<< endl; return false; } /// <summary> ///Convert string type to int type /// </summary> ///< param name = "STR" > string to be converted < / param > ///< returns > the converted integer of the string < / returns > int stringToInt(string str) { // Determine whether the string is empty if (str.empty()) { cout << "Data error, please check the file data!" << endl; return 0; } return stoi(str); // Convert string to integer } /// <summary> ///Empty file contents /// </summary> ///< param name = "filename" > file name < / param > void clearFile(const string fileName) { fstream file(fileName, ios::out); }
Welcome your comments!