Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <sstream>
- #include <vector>
- #include <Windows.h>
- using namespace std;
- void split(string data, string separator, vector<string>& splited);
- void replace(string data, string what, string to, string& out);
- struct Text {
- private:
- int cached_lines_count;
- int cached_char_count;
- vector<string> cached_lines;
- string cached_data;
- void update() {
- this->cached_data = this->data;
- split(this->cached_data, "\n", this->cached_lines);
- this->cached_lines_count = this->cached_lines.size();
- this->cached_char_count = this->cached_data.length();
- }
- void update_if_need() {
- if (data != cached_data) update();
- }
- public:
- int lines_count() {
- this->update_if_need();
- return this->cached_lines_count;
- }
- int char_count() {
- this->update_if_need();
- return this->cached_char_count;
- }
- vector<string> lines() {
- this->update_if_need();
- return this->cached_lines;
- }
- string data;
- };
- void open_file(fstream& file, string filepath, ios_base::openmode mode) {
- file.open(filepath, mode);
- }
- void close_file(fstream& file) {
- file.close();
- }
- void read_file(string filepath, string& data) {
- fstream f;
- open_file(f, filepath, fstream::in);
- stringstream buffer;
- buffer << f.rdbuf();
- data = buffer.str();
- close_file(f);
- }
- void write_to_file(string filepath, string data) {
- fstream f;
- open_file(f, filepath, fstream::out);
- f << data;
- close_file(f);
- }
- bool check_file_ext(string filepath) {
- vector<string> a;
- split(filepath, ".", a);
- string o;
- replace(a[a.size() - 1], " ", "", o);
- return o == "txt";
- }
- void split(string data, string separator, vector<string>& splited) {
- splited = vector<string>();
- int p;
- while ((p = data.find(separator)) != string::npos) {
- splited.push_back(data.substr(0, p));
- data.erase(0, p + separator.length());
- }
- //if (data != "")
- splited.push_back(data);
- }
- void replace(string data, string what, string to, string& out) {
- out = "";
- int p;
- while ((p = data.find(what)) != string::npos) {
- out += data.substr(0, p) + to;
- data.erase(0, p + what.length());
- }
- out += data;
- }
- void get_text(string filepath, Text& text) {
- string d;
- read_file(filepath, d);
- text.data = d;
- }
- void print_repeat(string what, int count) {
- for (int i = 0; i < count; i++) {
- cout << what;
- }
- }
- void print_extended(string what, int count, char fill) {
- print_repeat(string({ fill }), count - what.length());
- cout << what;
- }
- void print_text_data(Text text) {
- int m_line_num_length = to_string(text.lines_count()).length() + 2;
- string info = "First character index";
- int l = max(m_line_num_length, info.length());
- cout << info << "|";
- cout << "---File content---" << endl;
- int s = 0;
- for (int i = 0; i < text.lines_count(); i++) {
- string line = text.lines()[i];
- if (line != "" || i != text.lines_count() - 1) print_extended(to_string(s), l, ' ');
- else print_extended("-", l, ' ');
- cout << "|";
- cout << line << endl;
- s += line.length() + 1;
- }
- print_repeat("-", l);
- cout << "|";
- cout << "--------EOF-------" << endl;
- cout << "Characters length: " << text.char_count() << endl;
- cout << "Lines length: " << text.lines_count() << endl;
- cout << endl;
- }
- void rm_char_end(string& data, int count) {
- if (data.length() < count) {
- cout << "Too many symbols to remove" << endl;
- return;
- }
- data = data.substr(0, data.length() - count);
- }
- void first_to_upper(string& data) {
- int l = data.length() - 1;
- unsigned char* cur;
- for (int i = 0; i < l; i++) {
- cur = (unsigned char*)&data[i];
- if (tolower(*cur) == *cur &&
- (i == 0 ||
- (tolower(data[i - 1]) == data[i - 1] && toupper(data[i - 1]) == data[i - 1]))) {
- if (i != 0) {
- unsigned char d = data[i - 1];
- if (tolower(d) != d || toupper(d) != d) continue;
- }
- *cur = toupper(*cur);
- }
- }
- }
- void add_to_end(string& data, string add_data) {
- data += add_data;
- }
- void get_integer(void message(), int& integer, pair<int, int> limitation = {-1,-1}) {
- char* eptr;
- string inp;
- do {
- message();
- cin >> inp;
- cin.clear();
- integer = strtol(inp.c_str(), &eptr, 10);
- } while (*eptr != '\0' ||
- ((limitation.first != -1 && limitation.first > integer) ||
- (limitation.second != -1 && limitation.second < integer)));
- }
- void get_filepath(string& path, ios_base::openmode mode = fstream::in) {
- fstream file;
- struct stat b;
- do {
- file.close();
- cout << "Enter filepath:" << endl;
- cin >> path;
- cin.clear();
- file.open(path, mode);
- } while (stat(path.c_str(), &b) != 0 || !file);
- file.close();
- }
- void save_changes(Text t, string old_filepath) {
- cout << "Saving file (old filepath: " << old_filepath << ")" << endl;
- string path;
- get_filepath(path, fstream::out);
- write_to_file(path, t.data);
- }
- void print_selection_menu() {
- cout << "Select an action:" << endl;
- cout << "1 - Remove characters from the end" << endl;
- cout << "2 - Make all first charaters uppercase" << endl;
- cout << "3 - Add characters to the end" << endl;
- cout << "4 - Save and exit" << endl;
- cout << "5 - Exit without save" << endl;
- }
- void get_selection(int& sel) {
- get_integer(print_selection_menu, sel, {1, 5});
- }
- void f_act(Text& t) {
- auto mes = [] { cout << "Enter characters count to remove from the end: " << endl; };
- int to_rm;
- get_integer(mes, to_rm, { 1, t.char_count() });
- rm_char_end(t.data, to_rm);
- }
- void s_act(Text& t) {
- first_to_upper(t.data);
- }
- void t_act(Text& t) {
- cout << "Enter text to add to the end (Enter + Ctrl+Z + Enter to stop): " << endl;
- string s;
- cin.ignore();
- getline(cin, s, static_cast<char>(EOF));
- cin.clear();
- s = s.substr(0, s.length() - 1);
- add_to_end(t.data, s);
- }
- void actions(Text t, string old_filepath) {
- do {
- int sel;
- get_selection(sel);
- switch (sel) {
- case 1:
- if (t.data == "") {
- cout << endl;
- cout << "There is no characters to remove" << endl;
- cout << endl;
- break;
- }
- f_act(t);
- break;
- case 2:
- s_act(t);
- break;
- case 3:
- t_act(t);
- break;
- case 4:
- save_changes(t, old_filepath);
- return;
- case 5:
- return;
- }
- print_text_data(t);
- } while (true);
- }
- int main() {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- setlocale(LC_ALL, "Russian");
- string filepath;
- get_filepath(filepath);
- Text text;
- get_text(filepath, text);
- print_text_data(text);
- actions(text, filepath);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment