Sc3ric

lab10

May 10th, 2023 (edited)
574
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.36 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <vector>
  6. #include <Windows.h>
  7.  
  8. using namespace std;
  9.  
  10. void split(string data, string separator, vector<string>& splited);
  11. void replace(string data, string what, string to, string& out);
  12.  
  13. struct Text {
  14. private:
  15.  
  16.     int cached_lines_count;
  17.     int cached_char_count;
  18.     vector<string> cached_lines;
  19.     string cached_data;
  20.  
  21.     void update() {
  22.         this->cached_data = this->data;
  23.  
  24.         split(this->cached_data, "\n", this->cached_lines);
  25.  
  26.         this->cached_lines_count = this->cached_lines.size();
  27.         this->cached_char_count = this->cached_data.length();
  28.     }
  29.  
  30.     void update_if_need() {
  31.         if (data != cached_data) update();
  32.     }
  33.  
  34.  
  35. public:
  36.  
  37.     int lines_count() {
  38.         this->update_if_need();
  39.  
  40.         return this->cached_lines_count;
  41.     }
  42.     int char_count() {
  43.         this->update_if_need();
  44.  
  45.         return this->cached_char_count;
  46.     }
  47.  
  48.     vector<string> lines() {
  49.         this->update_if_need();
  50.  
  51.         return this->cached_lines;
  52.     }
  53.  
  54.     string data;
  55. };
  56.  
  57. void open_file(fstream& file, string filepath, ios_base::openmode mode) {
  58.     file.open(filepath, mode);
  59. }
  60.  
  61. void close_file(fstream& file) {
  62.     file.close();
  63. }
  64.  
  65.  
  66. void read_file(string filepath, string& data) {
  67.     fstream f;
  68.     open_file(f, filepath, fstream::in);
  69.     stringstream buffer;
  70.     buffer << f.rdbuf();
  71.     data = buffer.str();
  72.     close_file(f);
  73. }
  74.  
  75. void write_to_file(string filepath, string data) {
  76.     fstream f;
  77.     open_file(f, filepath, fstream::out);
  78.     f << data;
  79.     close_file(f);
  80. }
  81.  
  82. bool check_file_ext(string filepath) {
  83.     vector<string> a;
  84.     split(filepath, ".", a);
  85.     string o;
  86.     replace(a[a.size() - 1], " ", "", o);
  87.     return o == "txt";
  88. }
  89.  
  90.  
  91. void split(string data, string separator, vector<string>& splited) {
  92.     splited = vector<string>();
  93.     int p;
  94.     while ((p = data.find(separator)) != string::npos) {
  95.         splited.push_back(data.substr(0, p));
  96.         data.erase(0, p + separator.length());
  97.     }
  98.     //if (data != "")
  99.     splited.push_back(data);
  100. }
  101.  
  102. void replace(string data, string what, string to, string& out) {
  103.     out = "";
  104.     int p;
  105.     while ((p = data.find(what)) != string::npos) {
  106.         out += data.substr(0, p) + to;
  107.         data.erase(0, p + what.length());
  108.     }
  109.     out += data;
  110. }
  111.  
  112.  
  113. void get_text(string filepath, Text& text) {
  114.     string d;
  115.     read_file(filepath, d);
  116.  
  117.     text.data = d;
  118. }
  119.  
  120. void print_repeat(string what, int count) {
  121.     for (int i = 0; i < count; i++) {
  122.         cout << what;
  123.     }
  124. }
  125.  
  126. void print_extended(string what, int count, char fill) {
  127.     print_repeat(string({ fill }), count - what.length());
  128.     cout << what;
  129. }
  130.  
  131. void print_text_data(Text text) {
  132.     int m_line_num_length = to_string(text.lines_count()).length() + 2;
  133.  
  134.     string info = "First character index";
  135.  
  136.     int l = max(m_line_num_length, info.length());
  137.  
  138.     cout << info << "|";
  139.  
  140.     cout << "---File content---" << endl;
  141.  
  142.     int s = 0;
  143.  
  144.     for (int i = 0; i < text.lines_count(); i++) {
  145.         string line = text.lines()[i];
  146.         if (line != "" || i != text.lines_count() - 1) print_extended(to_string(s), l, ' ');
  147.         else print_extended("-", l, ' ');
  148.         cout << "|";
  149.         cout << line << endl;
  150.  
  151.         s += line.length() + 1;
  152.     }
  153.  
  154.     print_repeat("-", l);
  155.     cout << "|";
  156.  
  157.     cout << "--------EOF-------" << endl;
  158.  
  159.     cout << "Characters length: " << text.char_count() << endl;
  160.     cout << "Lines length: " << text.lines_count() << endl;
  161.  
  162.     cout << endl;
  163. }
  164.  
  165.  
  166. void rm_char_end(string& data, int count) {
  167.     if (data.length() < count) {
  168.         cout << "Too many symbols to remove" << endl;
  169.         return;
  170.     }
  171.  
  172.     data = data.substr(0, data.length() - count);
  173. }
  174.  
  175. void first_to_upper(string& data) {
  176.     int l = data.length() - 1;
  177.  
  178.     unsigned char* cur;
  179.  
  180.     for (int i = 0; i < l; i++) {
  181.         cur = (unsigned char*)&data[i];
  182.  
  183.         if (tolower(*cur) == *cur &&
  184.             (i == 0 ||
  185.                 (tolower(data[i - 1]) == data[i - 1] && toupper(data[i - 1]) == data[i - 1]))) {
  186.             if (i != 0) {
  187.                 unsigned char d = data[i - 1];
  188.  
  189.                 if (tolower(d) != d || toupper(d) != d) continue;
  190.  
  191.             }
  192.  
  193.             *cur = toupper(*cur);
  194.         }
  195.     }
  196. }
  197.  
  198. void add_to_end(string& data, string add_data) {
  199.     data += add_data;
  200. }
  201.  
  202.  
  203. void get_integer(void message(), int& integer, pair<int, int> limitation = {-1,-1}) {
  204.     char* eptr;
  205.  
  206.     string inp;
  207.  
  208.     do {
  209.         message();
  210.         cin >> inp;
  211.         cin.clear();
  212.         integer = strtol(inp.c_str(), &eptr, 10);
  213.     } while (*eptr != '\0' ||
  214.         ((limitation.first != -1 && limitation.first > integer) ||
  215.             (limitation.second != -1 && limitation.second < integer)));
  216. }
  217.  
  218.  
  219. void get_filepath(string& path, ios_base::openmode mode = fstream::in) {
  220.     fstream file;
  221.  
  222.     struct stat b;
  223.  
  224.     do {
  225.         file.close();
  226.         cout << "Enter filepath:" << endl;
  227.         cin >> path;
  228.         cin.clear();
  229.         file.open(path, mode);
  230.     } while (stat(path.c_str(), &b) != 0 || !file);
  231.     file.close();
  232. }
  233.  
  234. void save_changes(Text t, string old_filepath) {
  235.     cout << "Saving file (old filepath: " << old_filepath << ")" << endl;
  236.     string path;
  237.     get_filepath(path, fstream::out);
  238.     write_to_file(path, t.data);
  239. }
  240.  
  241.  
  242. void print_selection_menu() {
  243.     cout << "Select an action:" << endl;
  244.     cout << "1 - Remove characters from the end" << endl;
  245.     cout << "2 - Make all first charaters uppercase" << endl;
  246.     cout << "3 - Add characters to the end" << endl;
  247.     cout << "4 - Save and exit" << endl;
  248.     cout << "5 - Exit without save" << endl;
  249. }
  250.  
  251. void get_selection(int& sel) {
  252.     get_integer(print_selection_menu, sel, {1, 5});
  253. }
  254.  
  255. void f_act(Text& t) {
  256.     auto mes = [] { cout << "Enter characters count to remove from the end: " << endl; };
  257.  
  258.     int to_rm;
  259.     get_integer(mes, to_rm, { 1, t.char_count() });
  260.  
  261.     rm_char_end(t.data, to_rm);
  262. }
  263.  
  264. void s_act(Text& t) {
  265.     first_to_upper(t.data);
  266. }
  267.  
  268. void t_act(Text& t) {
  269.     cout << "Enter text to add to the end (Enter + Ctrl+Z + Enter to stop): " << endl;
  270.     string s;
  271.     cin.ignore();
  272.     getline(cin, s, static_cast<char>(EOF));
  273.     cin.clear();
  274.     s = s.substr(0, s.length() - 1);
  275.  
  276.     add_to_end(t.data, s);
  277. }
  278.  
  279. void actions(Text t, string old_filepath) {
  280.     do {
  281.         int sel;
  282.         get_selection(sel);
  283.  
  284.         switch (sel) {
  285.         case 1:
  286.             if (t.data == "") {
  287.                 cout << endl;
  288.                 cout << "There is no characters to remove" << endl;
  289.                 cout << endl;
  290.                 break;
  291.             }
  292.             f_act(t);
  293.             break;
  294.         case 2:
  295.             s_act(t);
  296.             break;
  297.         case 3:
  298.             t_act(t);
  299.             break;
  300.         case 4:
  301.             save_changes(t, old_filepath);
  302.             return;
  303.         case 5:
  304.             return;
  305.         }
  306.  
  307.         print_text_data(t);
  308.     } while (true);
  309. }
  310.  
  311.  
  312.  
  313. int main() {
  314.     SetConsoleCP(1251);
  315.     SetConsoleOutputCP(1251);
  316.     setlocale(LC_ALL, "Russian");
  317.  
  318.     string filepath;
  319.     get_filepath(filepath);
  320.  
  321.     Text text;
  322.     get_text(filepath, text);
  323.  
  324.  
  325.     print_text_data(text);
  326.  
  327.     actions(text, filepath);
  328.  
  329.     return 0;
  330. }
  331.  
Advertisement
Add Comment
Please, Sign In to add comment