您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

407 行
7.9 KiB

  1. /*
  2. * Written by : BinHong Lee
  3. * Last edited : 5/12/2016
  4. */
  5. #include <iostream>
  6. #include <string>
  7. #include <stack>
  8. #include <fstream>
  9. #include "Person.cpp"
  10. using namespace std;
  11. //Declaration of functions
  12. void getUser(string);
  13. void login();
  14. void adminLogin();
  15. void loggedIn();
  16. void registration();
  17. void editCredentials();
  18. void update(Person);
  19. void chgUsername();
  20. void chgPassword();
  21. void chgEmail();
  22. void chgPhoneNo();
  23. void quit();
  24. //Stacks to store the users' personal data
  25. stack<Person> users;
  26. //Declaration of place holding variables
  27. Person currentUser;
  28. string username;
  29. string password;
  30. string password2;
  31. string email;
  32. string phoneNo;
  33. int wrongPass = 0;
  34. int main()
  35. {
  36. //Reading from file to build the database
  37. ifstream fin("database.txt");
  38. while (!fin.eof())
  39. {
  40. //Reading in line-by-line into the placeholding variables
  41. fin >> username >> password >> email >> phoneNo;
  42. //Create the Person and push it into the stack
  43. Person temp(username, password, email, phoneNo);
  44. users.push(temp);
  45. }
  46. //Pop off the additional data added into the stack due to the empty line
  47. users.pop();
  48. getOption:
  49. //Display user input options
  50. cout << "Please choose one of the following options :" << endl;
  51. cout << "Log In - 1" << endl;
  52. cout << "Registration - 2" << endl;
  53. cout << "Exit - 0" << endl;
  54. //Get user input
  55. int choice;
  56. cin >> choice;
  57. //Switch according to user input
  58. switch (choice)
  59. {
  60. case 1:
  61. login();
  62. break;
  63. case 2:
  64. registration();
  65. break;
  66. case 0:
  67. break;
  68. default:
  69. //Display error message
  70. cout << "Invalid input. Please try again." << endl;
  71. goto getOption;
  72. }
  73. //Saving data into file
  74. ofstream fout("database.txt");
  75. //Check if the stack is empty
  76. while (!users.empty())
  77. {
  78. //Move the data into the files each Person per line
  79. fout << users.top().getName() << " " << users.top().getPassword() << " " << users.top().getEmail() << " " << users.top().getPhoneNo() << " " << endl;
  80. //Pop the Person out of stack after the data is moved
  81. users.pop();
  82. }
  83. //End the program
  84. return 0;
  85. }
  86. void getUser()
  87. {
  88. //Duplicate the current stack to be checked through
  89. stack<Person> temp = users;
  90. //Loop while the temporary stack is not empty
  91. while (!temp.empty())
  92. {
  93. //Check if the username match the query
  94. //If so, set it as the currentUser
  95. if (users.top().getName() == username) currentUser = users.top();
  96. //Pop the checked user
  97. users.pop();
  98. }
  99. //Throw invalid_argument error to be caught if the person is not found
  100. throw std::invalid_argument("");
  101. }
  102. void login()
  103. {
  104. //If the user already has 3 fail attempt to login
  105. if (wrongPass >= 3)
  106. {
  107. //Print error message and exit
  108. cout << "Too much failed login attempt. The program will now be terminated." << endl;
  109. quit();
  110. }
  111. try {
  112. //Ask for username
  113. cout << "Username:";
  114. cin >> username;
  115. //Ask for password
  116. cout << "Password:";
  117. cin >> password;
  118. //Get the user
  119. getUser();
  120. } catch (invalid_argument inae) {
  121. //Print error message
  122. cout << "Invalid username or password. Please try again.";
  123. //Increase wrongPass count that indicate the amount of times of invalid
  124. //credentials input by the user
  125. wrongPass++;
  126. login();
  127. }
  128. //Check if the password is correct
  129. if (!currentUser.checkPassword(password))
  130. {
  131. //Print error message
  132. cout << "Invalid username or password. Please try again.";
  133. //Increase wrongPass count that indicate the amount of times of invalid
  134. //credentials input by the user
  135. wrongPass++;
  136. login();
  137. }
  138. //User is successfully logged in
  139. loggedIn();
  140. }
  141. void registration()
  142. {
  143. //Initialize boolean
  144. bool available;
  145. do
  146. {
  147. try
  148. {
  149. //Get username
  150. cout << "Username: ";
  151. cin >> username;
  152. //Check if username is already in use
  153. //If not, it will throw an invalid_argument error to be caught
  154. getUser();
  155. //Print error message
  156. cout << "Username unavailable. Please try again." << endl;
  157. //Set available as false and continue the loop
  158. available = false;
  159. //Catch the invalid_argument error thrown by getUser()
  160. } catch (invalid_argument inae)
  161. {
  162. //Set available to true and quit the loop
  163. available = true;
  164. }
  165. } while (available == false);
  166. //Print success message
  167. cout << "Username is available." << endl;
  168. do
  169. {
  170. //Get password
  171. cout << "Password : ";
  172. cin >> password;
  173. //Confirm password
  174. cout << "Confirm password :";
  175. cin >> password2;
  176. //Print error message if both password is not the same
  177. if (password != password2)
  178. cout << "Password unmatched. Please try again.";
  179. //Loop until both password input is the same
  180. } while (password != password2);
  181. //Get email
  182. cout << "Email : ";
  183. cin >> email;
  184. //Get phone number
  185. cout << "Phone No. : ";
  186. cin >> phoneNo;
  187. //Create and push the new 'Person' into stack
  188. Person newUser(username, password, email, phoneNo);
  189. users.push(newUser);
  190. //Print success message
  191. cout << "Account is successfully registered." << endl;
  192. //Automatically login user
  193. currentUser = newUser;
  194. loggedIn();
  195. }
  196. void loggedIn()
  197. {
  198. int choice;
  199. cout << "Please choose one of the following option :" << endl;
  200. cout << "View credentials - 1" << endl;
  201. cout << "Edit credentials - 2" << endl;
  202. cout << "Exit - 0" << endl;
  203. cin >> choice;
  204. switch (choice)
  205. {
  206. case 1:
  207. cout << "Username : " << currentUser.getName() << "\nEmail : " << currentUser.getEmail() << "\nPhone No. : " << currentUser.getPhoneNo() << endl;
  208. loggedIn();
  209. break;
  210. case 2:
  211. editCredentials();
  212. loggedIn();
  213. break;
  214. case 0:
  215. quit();
  216. default:
  217. cout << "Invalid option. Please try again." << endl;
  218. cout << endl;
  219. loggedIn();
  220. }
  221. }
  222. void editCredentials()
  223. {
  224. int choice;
  225. cout << "Which of the following to edit?" << endl;
  226. cout << "Username - 1" << endl;
  227. cout << "Password - 2" << endl;
  228. cout << "Email - 3" << endl;
  229. cout << "Phone No. - 4" << endl;
  230. cout << "Exit - 0" << endl;
  231. cin >> choice;
  232. switch (choice)
  233. {
  234. case 1:
  235. chgUsername();
  236. break;
  237. case 2:
  238. chgPassword();
  239. break;
  240. case 3:
  241. chgEmail();
  242. break;
  243. case 4:
  244. chgPhoneNo();
  245. break;
  246. }
  247. }
  248. void update(Person newUser)
  249. {
  250. stack<Person> newUsers;
  251. while (!users.empty())
  252. {
  253. if (users.top().getName() == currentUser.getName())
  254. {
  255. cout << "replaced" << endl;
  256. newUsers.push(newUser);
  257. }
  258. else
  259. {
  260. newUsers.push(users.top());
  261. }
  262. users.pop();
  263. }
  264. users = newUsers;
  265. currentUser = newUser;
  266. }
  267. void chgUsername()
  268. {
  269. bool available;
  270. Person newUsers;
  271. do
  272. {
  273. available = true;
  274. cout << available << endl;
  275. cout << "Username : ";
  276. cin >> username;
  277. stack<Person> temp = users;
  278. while (!temp.empty())
  279. {
  280. if (temp.top().getName() == username)
  281. {
  282. cout << "Username unavailable. Please try again." << endl;
  283. cout << temp.top().getName() << " " << temp.top().getPhoneNo() << endl;
  284. available = false;
  285. break;
  286. }
  287. temp.pop();
  288. }
  289. } while (available == false);
  290. cout << "Username is available." << endl;
  291. Person newPerson(username, currentUser.getPassword(), currentUser.getEmail(), currentUser.getPhoneNo());
  292. update(newPerson);
  293. cout << "Username is updated." << endl;
  294. }
  295. void chgPassword()
  296. {
  297. cout << "Please input the current password : ";
  298. cin >> password;
  299. while (!currentUser.checkPassword(password))
  300. {
  301. cout << "Wrong password. Please try again." << endl;
  302. wrongPass++;
  303. cout << "Please input the current password : ";
  304. cin >> password;
  305. }
  306. do {
  307. cout << "Please input the new password : ";
  308. cin >> password;
  309. cout << "Please confirm your new password : ";
  310. cin >> password2;
  311. } while(password2 != password);
  312. currentUser.setPassword(password);
  313. update(currentUser);
  314. }
  315. void chgEmail()
  316. {
  317. cout << "Please input the new email : ";
  318. cin >> email;
  319. currentUser.setEmail(email);
  320. update(currentUser);
  321. }
  322. void chgPhoneNo()
  323. {
  324. cout << "Please input the new phone no. : ";
  325. cin >> phoneNo;
  326. currentUser.setPhoneNo(phoneNo);
  327. update(currentUser);
  328. }
  329. void quit()
  330. {
  331. ofstream fout("database.txt");
  332. while (!users.empty())
  333. {
  334. fout << users.top().getName() << " " << users.top().getPassword() << " " << users.top().getEmail() << " " << users.top().getPhoneNo() << " " << endl;
  335. users.pop();
  336. }
  337. exit (EXIT_SUCCESS);
  338. }