许久之前,在vector读写那篇博客末尾。本人装13说要用C++完成简易的图书馆管理系统。
But, = =期间遇到一个难以攻克的难题。在对vector<Struct>读写时,会出现地址冲突。虽然在stackOverFlow发布过问题,也查找过相关资料。
很不幸运,还是没能解决。 = = 没办法,只是菜鸟。
-------------------------------------------------------- 分割线 -----------------------------------------------------------
但我还是尝试了另一种方法来进行读写操作,在Struct中增加一个toString()方法,不进行二进制读写,直接用输入输出流操作。
Lucky, 终于了结一心结。
下面上代码,注释不多,对sstream(字符串流)不熟悉的,可以查看下C++ Primer相关内容。
1 /* 2 * dataAndAlgorithm homework 3 * A simple student information administration system 4 * windy 2016/09/19 5 */ 6 #include "stdafx.h" 7 #include <string> 8 #include <sstream> 9 #include <iostream> 10 #include <fstream> 11 12 13 class Student { 14 public: 15 std::string ID; 16 std::string name; 17 std::string birthday; 18 std::string sex; 19 std::string health; 20 Student(const std::string& _id = "",const std::string& _name = "",const std::string& _birth = "",const std::string& _sex = "",const std::string& _heal ="") 21 :ID(_id),name(_name),birthday(_birth),sex(_sex),health(_heal){} 22 const std::string toString() { 23 return this->ID + " " + this->name + " " + this->birthday + " " + this->sex + " " + this->health + "\n"; 24 } 25 void display() { 26 std::cout << "\tID:" << this->ID << "\n" 27 << "\tName:" << this->name << "\n" 28 << "\tBirthday:" << this->birthday << "\n" 29 << "\tSex:" << this->sex << "\n" 30 << "\tHealth:" << this->health << "\n\n"; 31 32 } 33 Student& operator = (const Student& t) { 34 ID = t.ID; 35 name = t.name; 36 birthday = t.birthday; 37 sex = t.sex; 38 health = t.health; 39 return *this; 40 } 41 }; 42 //create my list 43 class MyList { 44 private: 45 struct _List 46 { 47 Student element; 48 _List* next; 49 _List(const Student& _ele = Student(), _List* _next = NULL):element(_ele), next(_next){} 50 }; 51 public: 52 //constructor 53 MyList(){ 54 head = NULL; 55 size = 0; 56 } 57 // method add / push_back new node 58 // @return void #insert innformation into the list 59 bool add(const Student& newStud) { 60 if (NULL == this->head) { 61 this->head = new _List(newStud, NULL); 62 size++; 63 return true; 64 } 65 _List* curr = this->head; 66 while (curr->next != NULL) { 67 curr = curr->next; 68 } 69 curr->next = new _List(newStud, NULL); 70 size++; 71 return true; 72 } 73 // method search 74 // @return Student 75 Student& search(const std::string& ID) const{ 76 _List* curr = this->head; 77 while (curr) { 78 if (curr->element.ID == ID) 79 return curr->element; 80 curr = curr->next; 81 } 82 return Student(); //return EMPTY student struct 83 } 84 // method erase 85 // @return bool #TURE for erase successfully, or failed. 86 bool erase(const std::string& ID) { 87 if (this->head->element.ID == ID) { 88 _List* tmp = this->head; 89 this->head = this->head->next; 90 delete tmp; 91 return true; 92 } 93 _List* curr = this->head; 94 while (curr != NULL) { 95 if (curr->next->element.ID == ID) { 96 _List* tmp = curr->next; 97 curr->next = tmp->next; 98 delete tmp; 99 return true; 100 } 101 curr = curr->next; 102 } 103 return false; 104 } 105 // method update 106 // @return bool 107 bool update(const std::string& ID){ 108 Student& studForUpdate = search(ID); 109 if (studForUpdate.ID != "") { 110 std::cout << "The following is the information of the student." << std::endl; 111 studForUpdate.display(); 112 113 std::cout << "Please input the number to choose the Update-Item." << std::endl; 114 std::cout << "\t1:ID" << "\t2:Name" << "\t3:Birthday" << "\t4:Sex" << "\t5:Health" << std::endl; 115 int choice; 116 std::cin >> choice; 117 std::string value; 118 switch (choice) 119 { 120 case 1: { 121 std::cout << "Input new ID." << std::endl; 122 std::cin >> value; 123 studForUpdate.ID = value; 124 }break; 125 case 2: { 126 std::cout << "Input new name." << std::endl; 127 std::cin >> value; 128 studForUpdate.name = value; 129 }break; 130 case 3: { 131 std::cout << "Input new birthday." << std::endl; 132 std::cin >> value; 133 studForUpdate.birthday = value; 134 }break; 135 case 4: { 136 std::cout << "Input new sex." << std::endl; 137 std::cin >> value; 138 studForUpdate.sex = value; 139 }break; 140 case 5: { 141 std::cout << "Input new health." << std::endl; 142 std::cin >> value; 143 studForUpdate.health = value; 144 }break; 145 default: 146 std::cout << "Wrong choice!!!" << std::endl; 147 break; 148 } 149 return true; 150 } 151 else return false; 152 } 153 // method display 154 // @return void 155 void display() { 156 if (NULL == this->head) { 157 std::cout << "No Data!" << std::endl; 158 return; 159 } 160 _List* curr = this->head; 161 while (curr != NULL) { 162 curr->element.display(); 163 curr = curr->next; 164 } 165 } 166 // method clear 167 // @return void 168 void clear() { 169 _List* curr = head; 170 while (curr){ 171 _List* tmp = curr; 172 curr = curr->next; 173 delete tmp; 174 } 175 } 176 // method sort 177 // return void 178 void sort() { 179 for (int i = 0; i != size; i++) { 180 _List* prev = this->head; 181 _List* curr = prev->next; 182 while (curr != NULL) { 183 if (stringToInt(prev->element.ID) > stringToInt(curr->element.ID)) { 184 Student tmp = prev->element; 185 prev->element = curr->element; 186 curr->element = tmp; 187 } 188 prev = prev->next; 189 curr = curr->next; 190 } 191 } 192 } 193 // method write 194 // @return bool 195 bool write() { 196 std::fstream out("StudentSql.txt", std::ios::out|std::ios::app); 197 if (!out) { 198 std::cerr << "Can‘t open the file.Program exit!" << std::endl; 199 exit(-1); 200 } 201 std::cout << "Writing ... ..." << std::endl; 202 _List* curr = this->head; 203 while (curr != NULL) { 204 out << curr->element.toString(); 205 curr = curr->next; 206 } 207 out.close(); 208 return true; //std::cout << "Completed!" << std::endl; 209 } 210 // method read 211 // @return bool 212 bool read() { 213 // this->clear(); 214 char c; 215 std::cout << " Y to continue, N to cancel " << std::endl; 216 std::cin >> c; 217 if (c == ‘N‘ || c == ‘n‘) return false; 218 std::fstream in("StudentSql.txt",std::ios::in); 219 std::cout << "Reading ... ..." << std::endl; 220 if (!in) { 221 std::cerr << "Can‘t open the file.Program exit!" << std::endl; 222 exit(-1); 223 } 224 std::string line; 225 std::string word; 226 while (std::getline(in, line)) { 227 std::stringstream stream(line); 228 std::string strs[5]; 229 int i = 0; 230 while (stream >> word) { 231 strs[i++] = word; 232 } 233 this->add(Student(strs[0], strs[1], strs[2], strs[3], strs[4])); 234 } 235 in.close(); 236 return true; //read successfully 237 } 238 239 private: 240 _List* head; //DEFAULT NULL 241 int size; 242 int stringToInt(const std::string& str) { //max 1111 1111 11 243 int cnt = 0; 244 size_t sizeOfStr = str.size() > 10 ? 10 : str.size(); 245 int tens = 1; 246 for (size_t i = 0; i != sizeOfStr; i++, tens *= 10) { 247 cnt += tens*(str[sizeOfStr - i - 1] - ‘0‘); 248 } 249 return cnt; 250 } 251 }; 252 253 /* 254 * 实现学生健康情况管理的几个操作功能(新建、插入、删除、从文件读取、写入文件和查询、屏幕输出等功能)。 255 * 健康表中学生的信息有学号、姓名、出生日期、性别、身体状况等。 256 257 * 即系统的菜单功能项如下: 258 259 * ------新建学生健康表 get 260 * ------向学生健康表添加新的学生信息 get 261 * ------在健康表删除指定学生的信息(按学号操作) get 262 * ------为某个学生修改身体状况信息(按学号操作) get 263 * ------按学生的学号排序并显示结果 get 264 * ------在健康表中查询学生信息(按学生学号来进行查找) get 265 * ------在屏幕中输出全部学生信息 get 266 * ------从文件中读取所有学生健康表信息 get 267 * ------向文件写入所有学生健康表信息 get 268 * -----退出 269 */ 270 void header() { 271 std::cout << " Please input the number to choose a function\n\n" 272 << "\t1:Add " << "\t2:Update" << "\t3:Delete\n" 273 << "\t4:Sort " << "\t5:Search" << "\t6:Display\n" 274 << "\t7:Write " << "\t8:Read " << "\t9:Exit \t10:Clear the screen\n\n"; 275 } 276 void switcher() { 277 MyList* studList = new MyList(); 278 Student student; 279 while (true) 280 { 281 int i = 0; 282 std::cin >> i; 283 //temperature string value 284 std::string ID; 285 switch (i) { 286 case 1: { 287 std::cout << "Please input the information including /ID /name /birthday /sex /health_state ..." << std::endl; 288 std::cout << "ID..." << std::endl; 289 std::cin >> student.ID; 290 std::cout << "Name..." << std::endl; 291 std::cin >> student.name; 292 std::cout << "Birthday..." << std::endl; 293 std::cin >> student.birthday; 294 std::cout << "Sex..." << std::endl; 295 std::cin >> student.sex; 296 std::cout << "Health state...(Good/Averaged/Bad)" << std::endl; 297 std::cin >> student.health; 298 if (studList->add(student)) std::cout << "Add new student successfully!" << std::endl; 299 else std::cout << "Error adding!" << std::endl; 300 }break; 301 case 2: { 302 std::cout << "Please input the Student-ID." << std::endl; 303 std::cin >> ID; 304 if (studList->update(ID)) std::cout << "Update information successfully!" << std::endl; 305 else std::cout << "Error updating!" << std::endl; 306 }break; 307 case 3: { 308 std::cout << "Please input the Student-ID." << std::endl; 309 std::cin >> ID; 310 if (studList->erase(ID)) std::cout << "Delete information successfully!" << std::endl; 311 else std::cout << "Error deleting!" << std::endl; 312 }break; 313 case 4: { 314 studList->sort(); 315 }break; 316 case 5: { 317 std::cout << "Please input the Student-ID." << std::endl; 318 std::cin >> ID; 319 Student tmp = studList->search(ID); 320 if (tmp.ID != " ") tmp.display(); 321 else std::cout << "No such student!" << std::endl; 322 }break; 323 case 6: { 324 studList->display(); 325 }break; 326 case 7: { 327 if (studList->write()) std::cout << "Writing data successfully!" << std::endl; 328 else std::cout << "Error deleting!" << std::endl; 329 }break; 330 case 8: { 331 // std::cout << "Warning:Reading Data will destrory the data get in the console window\n" << std::endl; 332 if (studList->read()) std::cout << "Reading data successfully!" << std::endl; 333 else std::cout << "Error deleting!" << std::endl; 334 }break; 335 case 9: { 336 std::cout << "Warning:Make sure to write the data before exit!!\n Y to continue N to cancel " << std::endl; 337 char c; 338 std::cin >> c; 339 if (c == ‘N‘ || c == ‘n‘) break; 340 exit(-1); 341 }break; 342 case 10: { 343 system("cls"); 344 }break; 345 default: 346 break; 347 } 348 header(); 349 } 350 } 351 void doIt() { 352 header(); 353 switcher(); 354 } 355 356 357 int main() 358 { 359 doIt(); 360 system("pause"); 361 return 0; 362 }
末尾得点明下,虚数据库并没有检查重复项等功能,当然这属于设计一个数据库的范畴了。
时间: 2024-10-09 07:12:54