一、簡介
經過一段時間的c++基礎學習,是時候做一個較為全面的、運用c++功能的較復雜的項目練練手了。
運用軟件:Visual Studio (VS)。
題目:c++停車收費系統設計(某本編程書進階習題)
要求: 管理員登陸; 有停車、取車、查詢實時停車情況三個功能; 按照停車后時間分段計時收費。
分析: 管理員登陸需要密碼的不可視輸入,即輸入密碼輸出“*”,輸入錯誤用戶名或者錯誤密碼要報錯並且返回初始界面; 三個功能要基於寫入txt文件來實行,其中停車寫入信息,取車讀取信息並初始化信息,查詢輸出文件信息; 通過寫入文件的停車時間和取車時時間來計算停車分鍾,然后分段計時收費; 主界面需要實時顯示系統時間,並且在一段時間沒有操作后返回初始界面,標題要自定義為c++停車系統; 注意輸出格式; 文件信息應包括車位序號、車牌號、入庫時間(按指定位數輸出,如201808041128方便保存),停車時優先存在車位序號小的車位。
流程圖如下圖所示。
二、系統設計思路
1 void mainspace();//主界面,功能界面 2 3 void stop();//停車子函數 4 5 void move();//取車子函數 6 7 void check();//檢查當前庫存情況子函數 8 9 int money(int n);//計時收費子函數 10 11 void code();//密碼登陸子函數 12 13 string hide(int size);//輸入密碼輸出*子函數
根據流程圖大致需要以上幾個子函數,其中登陸界面包含code()和hide()兩個函數,主界面為mainspace(),三個操作功能一一對應一個子函數,其中取車多包含money()計時收費功能。
根據分析,這些函數應分別實現以下功能:
code():密碼登陸界面,用戶名與密碼預先設置好,若輸入錯誤則報錯並返回登陸界面,成功則進入主界面
hide():輸入一個字符時在操作台上不顯示本來字符,並輸出一個“*”
mainspace():輸出三個功能選擇,跳轉頁面
stop():將停車的三個信息(車位序號,車牌號,停車時間)寫入txt文件,車位序號小數字優先,其中停車時間由讀取當前系統時間進行處理
move():將選擇的車位序號的那一行信息刪除
check():將txt文件內容全部輸出
money():讀取選擇的車位序號的那一行信息,並處理計算得出停車時間並計時收費
三、函數功能實現
1 #include <iostream> 2 #include <ctime> 3 #include <string> 4 #include <stdio.h> 5 #include <conio.h> 6 #include <cstdlib> 7 #include <windows.h> 8 #include <iomanip> 9 #include <fstream> 10 using namespace std; 11 void mainspace();//主界面,功能界面 12 void stop();//停車子函數 13 void move();//取車子函數 14 void check();//檢查當前庫存情況子函數 15 int money(int n);//計時收費子函數 16 void code();//密碼登陸子函數 17 string hide(int size);//輸入密碼輸出*子函數 18 int park[10] = { 1,1 };//停車位序號,此時txt里預設了兩組數據 19 struct pay //返回自定義值 20 { 21 int timemin; 22 int money; 23 }pay1; 24 int main() 25 { 26 SetConsoleTitle("Stop Cars");//標題 27 while (1) { 28 time_t now = time(0); 29 tm *ltm = localtime(&now); 30 cout << 1900 + ltm->tm_year << "." << 1 + ltm->tm_mon << "." << ltm ->tm_mday << endl; 31 cout << ltm->tm_hour << ":" << ltm->tm_min << endl;//輸出時間 32 code(); 33 mainspace(); 34 Sleep(60000);//一段時間不操作返回初始界面 35 system("cls"); 36 } 37 } 38 void mainspace() 39 { 40 cout << "功能" << endl; 41 cout << "1.停車" << endl; 42 cout << "2.取車" << endl; 43 cout << "3.查詢" << endl; 44 int x; 45 cin >> x; 46 switch (x) 47 { 48 case 1:stop(); break; 49 case 2:move(); break; 50 case 3:check(); break; 51 } 52 } 53 void code() 54 { 55 string name = "linuas"; 56 string pw = "111111"; 57 string name1; 58 string code; 59 while (1) 60 { 61 cout << "請輸入用戶名:" << endl; 62 cin >> name1; 63 if (strcmp(name1.c_str(), name.c_str()) == 0) 64 { 65 system("cls"); 66 cout << "請輸入密碼:" << endl; 67 code = hide(7); 68 if (strcmp(pw.c_str(), code.c_str()) == 0) 69 { 70 system("cls"); 71 cout << "登陸成功!" << endl; 72 Sleep(2000); 73 break; 74 } 75 else cout << endl << "密碼錯誤!" << endl; 76 Sleep(2000); 77 system("cls"); 78 continue; 79 } 80 else cout << endl << "用戶名不存在!" << endl; 81 Sleep(2000); 82 system("cls"); 83 continue; 84 } 85 } 86 string hide(int size) 87 { 88 char c; 89 int count = 0; 90 char *password = new char[size]; // 動態申請空間 91 string str; 92 while ((c = _getch()) != '\r') { 93 94 if (c == 8) { // 退格 95 if (count == 0) { 96 continue; 97 } 98 putchar('\b'); // 回退一格 99 putchar(' '); // 輸出一個空格將原來的*隱藏 100 putchar('\b'); // 再回退一格等待輸入 101 count--; 102 } 103 if (count == size - 1) { // 最大長度為size-1 104 continue; 105 } 106 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) { // 密碼只可包含數字和字母 107 putchar('*'); // 接收到一個字符后, 打印一個* 108 password[count] = c; 109 count++; 110 } 111 } 112 password[count] = '\0'; 113 str = password; 114 return str; 115 } 116 void stop() 117 { 118 int n = 0; 119 int i = 0; 120 string str; 121 time_t now = time(0); 122 tm *ltm = localtime(&now);//獲取當前系統時間准備寫入 123 cout << "請輸入車牌號:" << endl; 124 cin >> str; 125 for (i = 0; i < 10; i++)//車位序號存在與否判定 126 { 127 if (park[i] != 1) 128 { 129 n = i; 130 break; 131 } 132 else continue; 133 } 134 park[n] = 1; 135 ofstream outfile("C:\\Users\\Linuas\\Desktop\\demo.txt", ios::app);//寫入文件式打開 136 outfile << endl << n << " " << str << " " << (1900 + ltm->tm_year) * 10000 + (1 + ltm->tm_mon) * 100 +ltm->tm_mday << " " << (ltm->tm_hour) * 100 + ltm->tm_min; 137 outfile.close();//寫入成功后關閉文件,切記! 138 cout << "停車成功" << endl; 139 Sleep(2000); 140 mainspace(); 141 } 142 void check() 143 { 144 ifstream myfile("C:\\Users\\Linuas\\Desktop\\demo.txt"); 145 string temp; 146 cout << "車位 " << "車牌號 " << "停車時間" << endl; 147 while (getline(myfile, temp)) 148 { 149 cout << temp << endl; 150 } 151 myfile.close(); 152 mainspace(); 153 } 154 void move() 155 { 156 ifstream file("C:\\Users\\Linuas\\Desktop\\demo.txt"); 157 string line; 158 int m, n, count = 0; 159 ofstream outfile("test2.txt", ios::out | ios::trunc); 160 cout << "您停車的車位是:" << endl; 161 cin >> m; 162 n=money(m)+1; 163 n = m + 1; 164 while (!file.eof()) { 165 getline(file, line); 166 if (count != n - 1)//保留行 167 outfile << line << endl; 168 count++; 169 } 170 outfile.close(); 171 file.close(); 172 ofstream outfile1("C:\\Users\\Linuas\\Desktop\\demo.txt", ios::out | ios::trunc); 173 fstream file1("test2.txt"); 174 while (!file1.eof()) { 175 getline(file1, line); 176 outfile1 << line << endl; 177 } 178 outfile1.close(); 179 file1.close(); 180 system("del test2.txt");//刪除中間文件 181 Sleep(2000); 182 mainspace(); 183 } 184 int money(int n) 185 { 186 fstream infile; 187 infile.open("C:\\Users\\Linuas\\Desktop\\demo.txt", ios::in); 188 string line; 189 int count = 0; 190 int a, b, c, d; 191 int b1, b2, c1, c2; 192 if (n == 0) { infile >> a >> line >> b >> c; } 193 else 194 { 195 while (!infile.eof()) { 196 getline(infile, line);//自動回車了一次 197 if (count == n - 1) 198 { 199 infile >> a >> line >> b >> c; 200 } 201 count++; 202 } 203 } 204 infile.close(); 205 d = b % 10000; 206 b1 = d % 100; 207 b2 = (d - b1) / 100; 208 c1 = c % 100; 209 c2 = (c - c1) / 100; 210 time_t now = time(0); 211 tm *ltm = localtime(&now); 212 pay1.timemin = (1 + ltm->tm_mon - b2) * 31 * 24 * 60 + (ltm->tm_mday - b1) * 24 * 60 + (ltm->tm_hour - c2) * 60 + ltm->tm_min - c1; 213 if (pay1.timemin <= 15) 214 { 215 pay1.money = 10; 216 } 217 else if (pay1.timemin <= 60) 218 { 219 pay1.money = 10 + pay1.timemin - 15; 220 } 221 else pay1.money = 60; 222 cout << "停車時間為" << pay1.timemin << "分鍾" << endl; 223 cout << "計時收費為" << pay1.money << "元" << endl; 224 Sleep(2000); 225 return n; 226 }
其中,
str1=str2 即字符串相等時,strcmp(str1.c_str(),str2.c_str())=0。 因為 strcmp 的參數應為 char ,因此 string 定義的參數要加 .c_str(),如上所示。 c++定義字符時,用 string 比用 char 數組要簡便的多得多。
四、程序運行圖示
登陸界面。
密碼不可視輸入。
主界面。
停車指令。
查詢現在停車場的情況。
此時txt文件情況。
取車計算時間與收費。
取車完后刪除那一行信息。
五、總結與分享
總的來說,這個項目還算有些內容,是即將開始的下一個項目的很好的台階。希望大家一起學習,在代碼學習的道路上越走越遠,頭發越掉越少!
下個項目,某為校招筆試題。
https://www.bilibili.com/read/cv899072
出處: bilibili
