diff --git a/C_C++/cpp_zh/source/main.cpp b/C_C++/cpp_zh/source/main.cpp new file mode 100644 index 0000000..55f0852 --- /dev/null +++ b/C_C++/cpp_zh/source/main.cpp @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "Employee.hpp" +#include "Worker.hpp" +#include "Contractee.hpp" +#include "Manager.hpp" +#include "Company.hpp" + +#include "help_message.h" + +using namespace std; + +/* globális példaértékű Company példány amin a "shell" operálhat + */ +Company mycompany("Beadandó Inc."); + +// Ambiens Osztály + +/* vissza adja a felhasználói input 'i'-edik mezejét, + * ahol a mezők white space szeparált string-ek ként vannak definiálva + */ +string parse_field(const string &line, int i) { + /* ezt a függvényt könyebb C string-ekkel implementálni, + * de az input std::string-ként jut ide kényelmesen, + * ezért "átváltjuk" + */ + const char * line_p = line.c_str(); // mező eleje + const char * end_p = line_p; // mező vége + for (int h = 0; h < i; h++) { // iterate + line_p = end_p; + while (isspace(*line_p)) { // find begin + ++line_p; + } + end_p = line_p; + while (!isspace(*end_p) // find end + && *end_p != '\0') { + ++end_p; + } + } + + string r = string(line_p, (end_p) - line_p); + + return r; +} + +/* felhasználói parancs értelmezése + */ +void command(const string &line) { + if (line == "q") { // "Quit" + throw int(); + } else if (line[0] == 'h') { // "Help" + puts(help_message); + return; + } else if (line.substr(0, 2) == "c ") { // "Create" + // ?! példa + if (line.size() < 5) { + return; + } + + string name = parse_field(line, 3); + //puts(name.c_str()); + + const char type = line[2]; + Employee * e; + switch (type) { + case 'w': { + e = (Employee *)(new Worker(name)); + } break; + case 'c': { + e = (Employee *)(new Contractee(name)); + } break; + case 'm': { + e = (Employee *)(new Manager(name, &mycompany)); + } break; + default: { + fputs("No employee created.", stderr); + return; + } break; + } + mycompany.employees.push_back(e); + puts("Employee created."); + return; + } else if (line.substr(0, 2) == "i ") { // "Info" + string id = parse_field(line, 2); + + Employee * e = mycompany.by_id(id); + if (e) { + e->details(); + puts(""); + } + + return; + } else if (line.substr(0, 2) == "m ") { // "Modify" + string id = parse_field(line, 2); + string modification = parse_field(line, 3); + + Employee * e = mycompany.by_id(id); + if (e) { + puts(e->modify(modification) ? "Modification performed." : "Modification error."); + } + + return; + } else if (line.substr(0, 2) == "d ") { // "Delete" + string id = parse_field(line, 2); + for (size_t i = 0; i < mycompany.employees.size(); i++) { + if (std::to_string(mycompany.employees[i]->id_m) == id) { + mycompany.employees.erase(mycompany.employees.begin() + i); + break; + } + } + + return; + } else if (line[0] == 'l') { // "List" + mycompany.print(); + return; + /* ------ + * a biztonsági mentés beégetve pusztán azért, + * hogy kényelmesebb legyen tesztelni + */ + } else if (line[0] == 'w') { // "Write" + mycompany.bak("./data/bak.csv"); + return; + } else if (line[0] == 'r') { // "Read" + mycompany.load("./data/bak.csv"); + return; + /* --- + */ + } else { + puts(help_message); + return; + } +} + +void filter(unordered_set &s, const char * const f) { + if (not *f) { return; } + + switch (f[0]) { + case '.': { // mező érték alapú szűrés + for (const auto &i : mycompany.employees) { + if (i->is_match(f)) { + s.insert(i); + } + } + } break; + default: { // feltehetőleg név + auto t = mycompany.by_name(f); + s.insert(t.begin(), t.end()); + } break; + } +} + +void search(string line) { + /* vissza térési lista; + * `set`, hogy ne kézzel kelljen duplikált bejegyzéseket ellenőrizni + */ + unordered_set r; + + /* space szeparált mezőnként szűrünk; + * a találatokat hozzáfűzzük az eddigiekhez; + * a szűrők között "vagy" kapcsolat áll fen + */ + char * dup = strdup(line.c_str()+1); + const char * delim = " "; + char * data = strtok(dup, delim); + int i = 0; + do { + filter(r, data); + ++i; + } while((data = strtok(NULL, delim), data)); + + for (const auto &e : r) { + e->details(); + puts(""); + } + + free(dup); +} + +/* top-level user input kezelő + */ +void input() { + // Beolvasás + string line; + fputs("$ ", stdout); + std::getline(std::cin, line); + + if (std::cin.eof()) { + puts(""); + throw int(); + } + + // Értelmezés + switch (line[0]) { + case '/': { // keresés + search(line); + } break; + default: { // parancs + command(line); + }; + } +} + +bool init() { + /* (lehet, hogy) keverjük a C/C++ I/O-t ezért szinkronizáljuk az + * std iostream objektumokat az stdio függvényekkel; + * számomra a C stílusú output és a C++ stílusú input esik kézre, + * valós projektben persze csak az egyiket használnám + */ + std::ios_base::sync_with_stdio(true); + return true; // megszokásból +} + +signed main() { + init(); + //#include "dummy_constructors.inc" + //mycompany.bak("./data/employees.csv"); + + if(mycompany.load("./data/employees.csv")) { + fputs("Fatális hiba: adatok betöltése sikertelen", stderr); + return 1; + } + + mycompany.print(); + + /* a kilépést kizárólag azért implementálom kivételel, + * mert szerettem volna kivételkezelést használni a programban, + * de máshol sem lett volna kevésbe értelmetlen + */ + try { + for (;;) { + input(); + } + } catch (...) { + ; + } + + return 0; +}