From 362d6bb65a4e808ee857af9ae7828bbbdbb6072f Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Tue, 30 Oct 2018 19:31:50 +0330 Subject: [PATCH 1/6] Adding Makefile --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ba74bb --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +run : main.o + ./run +main.o : + g++ main.cpp -o run -std=c++11 From bca2dace77f8530f5c5143439d16e59b464996fe Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Tue, 30 Oct 2018 19:32:46 +0330 Subject: [PATCH 2/6] Updating README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 68194b0..0bf5f41 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # stackoverflow-in-cpp A project for Advanced Programming students +To compile just type : +make run +^_^ From 26f9618cd1c144126cd8d3f1c8dd1f12bbc883b9 Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Tue, 30 Oct 2018 19:33:48 +0330 Subject: [PATCH 3/6] Delete README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 0bf5f41..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# stackoverflow-in-cpp -A project for Advanced Programming students -To compile just type : -make run -^_^ From 18a15d2b1a99738a4d4213928396dd33bac6e601 Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Tue, 30 Oct 2018 19:34:24 +0330 Subject: [PATCH 4/6] Updating README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..cdf752e --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# stackoverflow-in-cpp +A project for Advanced Programming students +To compile just type : +make run +^_^ From 941a7b1d666453249f068ea4fb48dd2953a06b11 Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Tue, 30 Oct 2018 19:35:08 +0330 Subject: [PATCH 5/6] Final commit --- main.cpp | 99 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/main.cpp b/main.cpp index 91d6c1b..6766dfa 100644 --- a/main.cpp +++ b/main.cpp @@ -1,15 +1,12 @@ #include #include +#include +#define SUCCESS true +#define ERROR false + + using namespace std; -/** - * In the name of God - * Homework 2 - * TODO: Complete this code using given TODO comments :). then remove TODOs - * feel free to edit code as you want and make it better - * Any questions? ask @devcom_support on telegram - * Good luck! - **/ enum UserType{ ADMIN, @@ -17,13 +14,30 @@ enum UserType{ }; -class UserAlreadyExistsException{}; //TODO: Give exceptions a better structure. search google (optional) +class UserAlreadyExistsException : public exception { // extending stdexception + public : + const char * what (){ + return "UserAlreadyExists"; + } + +}; + + +class LoginException : public exception { // extending stdexception + public : + const char * what (){ + return "Couldn't login with given credentials"; + } + +}; + + class AbstractUser{ // User structure public: virtual bool authenticate(string username, string password) = 0; - virtual bool deleteAccount(vector *users) = 0; //TODO: 1. implement this in User class. (You can't compile code and create instance of User until then). DON'T TOUCH ABSTRACT USER! - string username; + virtual void deleteAccount(vector *users) = 0; + string username; protected: string password; UserType type; @@ -43,26 +57,43 @@ class User : public AbstractUser{ return this->username == username && this->password == password; } - static User* login(vector *users, string username, string password){ //TODO: 2. handle user login errors with exceptions + void deleteAccount(vector *users){ + for (auto user = users->begin(); user != users->end(); user++){ + if (this->username == (*user)->username ){ // We want to delete just the current user's account ... + users->erase(user); + } + } + + } + + static User* login(vector *users, string username, string password){ for(auto user = users->begin(); user != users->end(); user++){ if((*user)->authenticate(username, password)){ return (User*) *user; } + } + LoginException LE; + throw LE; + return nullptr; } + + static void signup(vector *users, string username, string password){ - //Check if user with that username exists and throw UserAlreadyExistsException in that case - for(auto user = users->begin(); user != users->end(); user++) { //TODO: 3. this doesn't work. fix it!! - if ((*user)->username == username) { - UserAlreadyExistsException ex; - throw ex; - } + + for( auto user = users->begin(); user != users->end(); user++) { + + if((*user)->authenticate(username, password)) { //Fixing the function + UserAlreadyExistsException ex; + throw ex; + } + } - //Create user and add it to vector + users->push_back(new User(username, password, UserType::MEMBER)); } @@ -75,13 +106,13 @@ enum MenuState{ END }; -class AppDatabase { //Just holds runtime data. doesn't save anything +class AppDatabase { public: vector appUsers; - AppDatabase() { //Load initial data + AppDatabase() { appUsers.push_back(new User("admin", - "admin" /* password is unsafe! for test only */, + "admin" , UserType::ADMIN) ); } @@ -108,14 +139,16 @@ int main(){ cin >> username; cout << "Enter Password" << endl; cin >> password; - loggedInUser = User::login(&appDatabase.appUsers, username, password); - if (loggedInUser == nullptr) { - cout << "couldn't login with given credentials."; - } else { - menuState = MenuState::LOGGED_IN; + try{ //Handling user login errors with exceptions + loggedInUser = User::login(&appDatabase.appUsers, username, password); + menuState = MenuState::LOGGED_IN; + }catch(LoginException login_exception){ + cout << login_exception.what() << endl; + } break; - } + } + case '2': { string username, password; cout << "Enter Username" << endl; @@ -124,8 +157,8 @@ int main(){ cin >> password; try{ User::signup(&appDatabase.appUsers, username, password); - } catch (UserAlreadyExistsException e) { - cout << "Error: username already exists"; + } catch (UserAlreadyExistsException exist_exception) { + cout << exist_exception.what() << endl; } break; } @@ -165,6 +198,11 @@ int main(){ } break; } + case MenuState::END:{ + ; + } + + } } @@ -172,3 +210,4 @@ int main(){ } + From 525f1d49e014422dee0d5c885359e245be36e2cd Mon Sep 17 00:00:00 2001 From: Yasna1998 <37747761+Yasna1998@users.noreply.github.com> Date: Sat, 19 Jan 2019 01:26:24 +0330 Subject: [PATCH 6/6] Adding features --- main.cpp | 325 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 282 insertions(+), 43 deletions(-) diff --git a/main.cpp b/main.cpp index 6766dfa..417039b 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #define SUCCESS true #define ERROR false @@ -16,23 +18,19 @@ enum UserType{ class UserAlreadyExistsException : public exception { // extending stdexception public : - const char * what (){ - return "UserAlreadyExists"; - } - + const char * what (){ + return "UserAlreadyExists"; + } }; class LoginException : public exception { // extending stdexception public : - const char * what (){ - return "Couldn't login with given credentials"; - } - + const char * what (){ + return "Couldn't login with given credentials"; + } }; - - class AbstractUser{ // User structure public: virtual bool authenticate(string username, string password) = 0; @@ -40,30 +38,37 @@ class AbstractUser{ // User structure string username; protected: string password; + string email; UserType type; }; class User : public AbstractUser{ public: - - User(string username, string password, UserType type){ - this->username = username; + User(string username, string password, UserType type,string email){ + this->username = username; this->password = password; this->type = type; + this-> email = email; } bool authenticate(string username, string password){ - return this->username == username && this->password == password; + return this->username == username && this->password == password; } + static string user_information(User * user ){ + time_t now = time(0); + char* dt = ctime(&now); + tm *gmtm = gmtime(&now); + dt = asctime(gmtm); + return user->email +" " + user->username + " "+ dt;; + } void deleteAccount(vector *users){ for (auto user = users->begin(); user != users->end(); user++){ if (this->username == (*user)->username ){ // We want to delete just the current user's account ... users->erase(user); } } - } static User* login(vector *users, string username, string password){ @@ -71,33 +76,28 @@ class User : public AbstractUser{ if((*user)->authenticate(username, password)){ return (User*) *user; } - - } + } LoginException LE; throw LE; - - return nullptr; + return nullptr; } - - static void signup(vector *users, string username, string password){ - - - for( auto user = users->begin(); user != users->end(); user++) { - - if((*user)->authenticate(username, password)) { //Fixing the function + static User* signup(vector *users, string username, string password,string email){ + for( auto user = users->begin(); user != users->end(); user++) { + if((*user)->authenticate(username, password)) { //Fixing the function UserAlreadyExistsException ex; throw ex; } - } - - users->push_back(new User(username, password, UserType::MEMBER)); + User * new_user = new User(username, password, UserType::MEMBER,email); + users->push_back(new_user); + return new_user; } string username; + }; enum MenuState{ @@ -106,26 +106,96 @@ enum MenuState{ END }; + + +class Post{ + public: + int id; + string username; + string question; + vector answers; + int visited_counter ; + Post(int id,string username , string question ,vector _answers){ + this -> id = id ; + this -> username = username ; + this -> question = question; + for (int i = 0 ; i < _answers.size() ;i++){ + answers.push_back(_answers[i]); + } + this ->visited_counter = 0; + } +}; + + +void store_questions_answers(vector posts){ + ofstream questions_file; + questions_file.open("questions.txt"); + for (int i = 0 ; i < posts.size() ;i++){ + questions_file << "VISITED : " << posts[i]-> visited_counter << " TIMES" << endl; + questions_file << "==============================================" << endl; + questions_file << posts[i]->username << endl; + questions_file << i+1 <<" " << posts[i]->question << endl; + for (int j = 0 ; j < posts[i]->answers.size() ;j++){ + questions_file << posts[i]->answers[j] << endl; + } + questions_file << "==============================================" << endl; + } +} + + +void store_post(string username,vector posts){ + ofstream post_file; + string file_name = username+".txt"; + post_file.open(file_name); + for (int i = 0 ; i < posts.size() ;i++){ + post_file << "VISITED : " << posts[i]-> visited_counter << " TIMES" << endl; + if (posts[i]->username ==username){ + post_file << i+1 << " " << posts[i]->question << endl; + for (int j = 0 ; j < posts[i]->answers.size() ;j++){ + post_file << posts[i]->answers[j] << endl; + } + } + post_file << "==============================================" << endl; + } +} + +void set_id(vector posts){ + for (int i = 0 ; i < posts.size() ;i++){ + posts[i]-> id = i+1; + } +} + +int get_id(vector posts){ + return posts.size() ; +} + class AppDatabase { public: vector appUsers; - + vector posts; AppDatabase() { - appUsers.push_back(new User("admin", - "admin" , - UserType::ADMIN) - ); + appUsers.push_back(new User("abc","123" ,UserType::ADMIN,"YasnaKatebzadeh@gmail.com")); + vector admin_answers ; + admin_answers.push_back("a"); + admin_answers.push_back("b"); + Post * admin_post = new Post(1,"abc","How can we ask questions in stackoverflow ?",admin_answers); + posts.push_back(admin_post); } }; int main(){ + User * loggedInUser = nullptr; + User * new_user = nullptr; AppDatabase appDatabase; + store_questions_answers(appDatabase.posts); + store_post("yasnakateb",appDatabase.posts); + set_id(appDatabase.posts); MenuState menuState = MenuState::START; - + char choice; cout << "Welcome!" << endl; - + int user_counter = 1; while(menuState != MenuState::END){ switch (menuState){ case MenuState::START: { @@ -134,29 +204,194 @@ int main(){ cin >> choice; switch(choice) { case '1': { - string username, password; + string username, password,email; cout << "Enter Username" << endl; cin >> username; cout << "Enter Password" << endl; cin >> password; - try{ //Handling user login errors with exceptions - loggedInUser = User::login(&appDatabase.appUsers, username, password); - menuState = MenuState::LOGGED_IN; + + LOGGED_IN_STATE : + try{ + //Handling user login errors with exceptions + loggedInUser = User::login(&appDatabase.appUsers, username, password); + menuState = MenuState::LOGGED_IN; + string user_info = User::user_information(loggedInUser); + ofstream user_file; + string file_name = "log." + to_string (user_counter) + ".txt"; + user_file.open(file_name); + user_file << user_info; + user_file.close(); + user_counter ++; + char command; + cout << "1.See all posts" << endl; + cout << "2.Ask a question" << endl; + cout << "b.back" << endl; + cin >> command ; + switch(command){ + case '1': + { + ifstream questions_file; + questions_file.open("questions.txt"); + char str[255]; + while(questions_file) { + questions_file.getline(str, 255); // delim defaults to '\n' + if(questions_file) cout << str << endl; + } + + + questions_file.close(); + + char post_command ; + int id; + string new_answer; + + cout << "1.Answer a question" <> post_command; + switch(post_command){ + case '1':{ + cout << "Enter question's ID" << endl; + cin >> id; + for (int i = 0 ; i < appDatabase.posts.size();i++){ + if (appDatabase.posts[i]->id ==id ){ + appDatabase.posts[i]->visited_counter ++; + cout << "Enter your answer" << endl; + cin >> new_answer; + appDatabase.posts[i]->answers.push_back(new_answer); + + } + } + + store_questions_answers(appDatabase.posts); + store_post(username,appDatabase.posts); + set_id(appDatabase.posts); + + + } + break; + case '2':{ + int id ; + string new_question; + cout << "These are your posts" << endl; + cout << "==============================================" << endl; + ifstream user_post_file; + string file_name = username+".txt"; + user_post_file.open(file_name); + char str[255]; + + while(user_post_file) { + user_post_file.getline(str, 255); // delim defaults to '\n' + if(user_post_file) cout << str << endl; + + } + + cout << "Enter question's ID" << endl; + cin >> id ; + for (int i = 0 ; i < appDatabase.posts.size();i++){ + if (appDatabase.posts[i]->id ==id ){ + cout << "Enter your question" << endl; + cin >> new_question; + vector _answers; + Post *new_post = new Post(id,username ,new_question , _answers); + appDatabase.posts[i] = new_post; + + } + } + store_questions_answers(appDatabase.posts); + store_post(username,appDatabase.posts); + set_id(appDatabase.posts); + + + + } + break; + case '3':{ + int id; + cout << "Enter question's ID" << endl; + cin >> id ; + for (int i = 0 ; i < appDatabase.posts.size();i++){ + if (appDatabase.posts[i]->id ==id ){ + appDatabase.posts.erase (appDatabase.posts.begin()+i); + + + } + } + store_questions_answers(appDatabase.posts); + store_post(username,appDatabase.posts); + set_id(appDatabase.posts); + + } + + break; + + case '4':{ + menuState = MenuState :: LOGGED_IN; + continue; + } + break; + + case 'b':{ + goto LOGGED_IN_STATE; + } + break; + + } + + + } + break; + + case '2':{ + string new_question; + cout << "Enter your question" << endl; + cin >> new_question; + vector _answers; + int id = get_id(appDatabase.posts); + Post *new_post = new Post(id,username ,new_question , _answers); + appDatabase.posts[id] = new_post; + store_questions_answers(appDatabase.posts); + store_post(username,appDatabase.posts); + set_id(appDatabase.posts); + } + break; + + + case 'b':{ + menuState = MenuState::START; + continue; + } + + } + }catch(LoginException login_exception){ cout << login_exception.what() << endl; } + break; } case '2': { - string username, password; + string username, password ,email; cout << "Enter Username" << endl; cin >> username; cout << "Enter Password" << endl; cin >> password; + cout << "Enter Email" << endl; + cin >> email; try{ - User::signup(&appDatabase.appUsers, username, password); + new_user = User::signup(&appDatabase.appUsers, username, password,email); + string user_info = User::user_information(new_user); + ofstream user_file; + string file_name = "log." + to_string (user_counter) + ".txt"; + user_file.open(file_name); + user_file << user_info; + user_file.close(); + user_counter ++; } catch (UserAlreadyExistsException exist_exception) { cout << exist_exception.what() << endl; } @@ -173,9 +408,13 @@ int main(){ break; } case MenuState::LOGGED_IN: { - cout << "d.delete account\nl. logout\ne. exit\n"; + cout << "b.back\nd.delete account\nl. logout\ne. exit\n"; cin >> choice; switch(choice) { + case 'b':{ + menuState = MenuState::START; + } + break; case 'd': { loggedInUser->deleteAccount(&appDatabase.appUsers); cout << "Account successfully deleted";