From 91ebea47a6e175e9cc317cd72f9a60667c268127 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Sun, 26 Mar 2023 22:43:48 +0300 Subject: [PATCH 01/15] =?UTF-8?q?=D0=9D=D0=B5=D1=81=D0=BA=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D1=80=D0=B0=D0=B7=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D1=87=D0=B8=D1=82=D0=B0=D0=BB=20=D0=B7=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=97=D0=B0=D0=B4=D0=B0=D0=BB=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=BF=D1=80=D0=BE=D1=81=20=D1=80=D0=B0=D0=B7=D0=BD=D1=8B?= =?UTF-8?q?=D0=BC=20=D0=BB=D1=8E=D0=B4=D1=8F=D0=BC=20=D0=92=D1=81=D0=B5=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D1=82.=20=D0=AF=20=D0=B7=D0=BB?= =?UTF-8?q?=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 23 +++++++++++++ include/IOperation.hpp | 4 +++ src/IOperation.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 7 ++++ static/text.txt | 26 ++++++++++++++ static/zarplata.txt | 9 +++++ 6 files changed, 146 insertions(+) create mode 100644 Makefile create mode 100644 include/IOperation.hpp create mode 100644 src/IOperation.cpp create mode 100644 src/main.cpp create mode 100644 static/text.txt create mode 100644 static/zarplata.txt diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b538a56 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CXX := g++ +CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb + +BIN := bin +SRC := src +INCLUDE := include +LIB := lib + +LIBRARIES := +EXECUTABLE := main + + +all: $(BIN)/$(EXECUTABLE) + +run: clean all + clear + ./$(BIN)/$(EXECUTABLE) 'echo million$ | cat text.txt | cat zarplata.txt' + +$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp + $(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) + +clean: + -rm $(BIN)/* diff --git a/include/IOperation.hpp b/include/IOperation.hpp new file mode 100644 index 0000000..8682073 --- /dev/null +++ b/include/IOperation.hpp @@ -0,0 +1,4 @@ +#pragma once +#include + +void print(); \ No newline at end of file diff --git a/src/IOperation.cpp b/src/IOperation.cpp new file mode 100644 index 0000000..b8635aa --- /dev/null +++ b/src/IOperation.cpp @@ -0,0 +1,77 @@ +#include +#include +#include "IOperation.hpp" + +class IOperation { +public: + virtual void ProcessLine(const std::string& str) = 0; + virtual void HandleEndOfInput() = 0; + virtual void SetNextOperation(IOperation* operation) = 0; + virtual ~IOperation() {} +}; + + +class EchoOperation : public IOperation { +public: + EchoOperation() : next_operation_(nullptr) {} + EchoOperation(const std::string& str, IOperation* operation = nullptr) : str_(str), next_operation_(operation) {} + + void ProcessLine(const std::string& str) override { + std::cout << str << std::endl; + } + + void HandleEndOfInput() override { + ProcessLine(str_); + if(next_operation_) { + next_operation_->HandleEndOfInput(); + } + } + + void SetNextOperation(IOperation* operation) override { + next_operation_ = operation; + } +private: + const std::string& str_; + IOperation* next_operation_; +}; + + +class CatOperation : public IOperation { +public: + CatOperation() : file_(nullptr), next_operation_(nullptr) {} + CatOperation(const std::string file, IOperation* next_operation=nullptr) : file_(file), next_operation_(next_operation) {} + + void ProcessLine(const std::string& str) override { + if (!file_.is_open()) { + std::cerr << "Cannot open file: " << str << std::endl; + HandleEndOfInput(); + } + // читаем строки из файла и выводим их + std::string line; + while (std::getline(file_, line)) { + std::cout << line << std::endl; + } + HandleEndOfInput(); + } + + void HandleEndOfInput() override { + if (next_operation_) { + next_operation_->HandleEndOfInput(); + } + } + + void SetNextOperation(IOperation* operation) override { + next_operation_ = operation; + } + + ~CatOperation() { + std::cout << "Destructor CatOperation\n"; + if(next_operation_) { + delete next_operation_; + } + } + +private: + std::ifstream file_; + IOperation* next_operation_; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8abc6f0 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,7 @@ +#include +#include "IOperation.hpp" + +int main() { + std::cout << "Hello Easy C++ project!" << std::endl; + print(); +} \ No newline at end of file diff --git a/static/text.txt b/static/text.txt new file mode 100644 index 0000000..f9d88db --- /dev/null +++ b/static/text.txt @@ -0,0 +1,26 @@ +​Необходимо написать программу, реализующую функционал потокового текстового редактора с использованием ООП. +Необходимо реализовать поддержку операций: +cat - передает следующей операции сначала строки поданные на вход, затем строки из файла filename +echo - игнорирует строки поданные на вход, передает следующей операции строку +Выход одной операции подается на вход другой операции, операции разделяются символом '|'. +Если следующей операции нет, то строки выводятся в стандартный вывод (на экран). + +Для реализации обработки строк утверждается следующий интерфейс IOperation. +Наследник IOperation обязан реализовать методы: +void ProcessLine(const std::string& str); +void HandleEndOfInput() = 0; +void SetNextOperation(<умный/сырой указатель/ссылка на IOperation>) = 0; + +Каждая операция наследуется от интерфейса IOperation. +Программа должна парсить выражение, переданное в аргументах командной строки и строить конвеер из наследников IOperation. +Выражение можно парсить предельно строго ( например, недопускаются лишние пробелы или их отсутствие ) +Для упрощения парсера аргументы отдельных операций не допускают пробелы ( echo 1 2 3 недопустим как и cat file name.txt ) +Результат вычисления получается вызовом метода HandleEndOfInput у первой операции. +Пример (при вводе в терминале выражение с пробелами нужно обернуть, например, в одинарные кавычки) +./text_processor 'echo 1 | cat file_1.txt | cat file_2.txt' +1 +<содержимое file_1.txt> +<содержимое file_2.txt> + +Ваш вариант: +Добавьте к существующим операциям wc -c - операцию, которая выводит или передает дальше число суммарное число байт во всех переданных на вход строках \ No newline at end of file diff --git a/static/zarplata.txt b/static/zarplata.txt new file mode 100644 index 0000000..3141f69 --- /dev/null +++ b/static/zarplata.txt @@ -0,0 +1,9 @@ +На ваш счет зачислено 2_000_000$ +К переводу прикреплено сообщение: +"Дорогая, спасибой за вечер! Особенно его окончание!" +Баланса: все еще не хватает для беззаботной жизни + + + + + From 5dd8cf851604e7c875e6303a4858ceea31abb5b3 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Sun, 26 Mar 2023 22:48:17 +0300 Subject: [PATCH 02/15] Update readme --- README.md | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c70cd1a..4544ca3 100644 --- a/README.md +++ b/README.md @@ -7,32 +7,39 @@ --- ### DZ1 Вариант #13 > Parse file - How many groups from place -- Необходимо разработать программу, которая обрабатывает данные онлайн сервиса MusicBrainz. -Датасет можно скачать на официальном сайте MusicBrainz https://data.metabrainz.org/pub/musicbrainz/data/fullexport/ -Необходимый файл mbdump.tar.bz2. -Описание датасета находится по ссылке https://musicbrainz.org/doc/MusicBrainz_Database/Schema -Например, для Артиста диаграмма находится по ссылке https://wiki.musicbrainz.org/images/7/7e/artist_entity_details.svg -Файл датасета представляет из себя сжатый архив из множества текстовых файлов, где данные располагаются в строчках, а поля разделены символом табуляции \t -Каждая таблица на схемах представлена отдельным файлом с аналогичным названием +- ​Необходимо написать программу, реализующую функционал потокового текстового редактора с использованием ООП. +Необходимо реализовать поддержку операций: +cat - передает следующей операции сначала строки поданные на вход, затем строки из файла filename +echo - игнорирует строки поданные на вход, передает следующей операции строку +Выход одной операции подается на вход другой операции, операции разделяются символом '|'. +Если следующей операции нет, то строки выводятся в стандартный вывод (на экран). -- Скачать датасет по ссылке можно с помощью команды wget, например -wget https://data.metabrainz.org/pub/musicbrainz/data/fullexport/20230304-002037/mbdump.tar.bz2 -Полученный файл нужно распаковать -tar xvf mbdump.tar.bz2 -Все файлы кроме gender, area, artist, artist_type можно удалить с помощью команды rm. -Программа должна принимать необходимые для работы имена распакованных файлов в качестве аргументов командной строки и выводить данные в стандартный вывод. -Программа не должна использовать интерактивный ввод с клавиатуры, например, "введите имя файла", "введите необходимый год", "ведите q чтобы выйти" - такими программами не удобно пользоваться и их разработка занимает больше времени. + +- Для реализации обработки строк утверждается следующий интерфейс IOperation. +Наследник IOperation обязан реализовать методы: +void ProcessLine(const std::string& str); +void HandleEndOfInput() = 0; +void SetNextOperation(<умный/сырой указатель/ссылка на IOperation>) = 0; + +- Каждая операция наследуется от интерфейса IOperation. +Программа должна парсить выражение, переданное в аргументах командной строки и строить конвеер из наследников IOperation. +Выражение можно парсить предельно строго ( например, недопускаются лишние пробелы или их отсутствие ) +Для упрощения парсера аргументы отдельных операций не допускают пробелы ( echo 1 2 3 недопустим как и cat file name.txt ) +Результат вычисления получается вызовом метода HandleEndOfInput у первой операции. +Пример (при вводе в терминале выражение с пробелами нужно обернуть, например, в одинарные кавычки) +./text_processor 'echo 1 | cat file_1.txt | cat file_2.txt' +1 +<содержимое file_1.txt> +<содержимое file_2.txt> - Ваш вариант: -Вывести число групп созданных в месте, название которого передано в аргументах командной строки +Добавьте к существующим операциям wc -c - операцию, которая выводит или передает дальше число суммарное число байт во всех переданных на вход строках #### Run application ``` -./bin/main +./bin/main ``` -#### For example (With output): +#### For example: ``` -./bin/main "Chile" -Input: Chile, Id = 43 -Groups from this place = 828 +./bin/main 'echo million$ | cat text.txt | cat zarplata.txt' ``` --- \ No newline at end of file From 0aec724d380b5e79bc3e026288e6854279c76939 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Sun, 26 Mar 2023 22:49:38 +0300 Subject: [PATCH 03/15] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4544ca3..d709b28 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Platforms - Linux Ubuntu 22.04 --- -### DZ1 Вариант #13 +### DZ1 Вариант #11 > Parse file - How many groups from place - ​Необходимо написать программу, реализующую функционал потокового текстового редактора с использованием ООП. Необходимо реализовать поддержку операций: From 9f7bdead2f184fd17609b9c16109b0870c2da893 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Sun, 26 Mar 2023 22:50:07 +0300 Subject: [PATCH 04/15] Update readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index d709b28..1c8667c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ - Linux Ubuntu 22.04 --- ### DZ1 Вариант #11 -> Parse file - How many groups from place - ​Необходимо написать программу, реализующую функционал потокового текстового редактора с использованием ООП. Необходимо реализовать поддержку операций: cat - передает следующей операции сначала строки поданные на вход, затем строки из файла filename From 0d6fe1b4d051f2ca789938a750384d54f882955f Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 29 Mar 2023 19:53:00 +0300 Subject: [PATCH 05/15] Sigmentation fault --- include/CommandParser.hpp | 3 ++ include/IOperation.hpp | 108 +++++++++++++++++++++++++++++++++++++- src/CommandParser.cpp | 0 src/IOperation.cpp | 77 --------------------------- src/main.cpp | 39 +++++++++++++- 5 files changed, 147 insertions(+), 80 deletions(-) create mode 100644 include/CommandParser.hpp create mode 100644 src/CommandParser.cpp delete mode 100644 src/IOperation.cpp diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp new file mode 100644 index 0000000..7b53e08 --- /dev/null +++ b/include/CommandParser.hpp @@ -0,0 +1,3 @@ +#pragma once +#include + diff --git a/include/IOperation.hpp b/include/IOperation.hpp index 8682073..e699279 100644 --- a/include/IOperation.hpp +++ b/include/IOperation.hpp @@ -1,4 +1,110 @@ #pragma once #include +#include -void print(); \ No newline at end of file +class IOperation { +public: + IOperation() : next_operation_(nullptr) {} + IOperation(IOperation * op) : next_operation_(op) {} + virtual void ProcessLine(const std::string& str) = 0; + virtual void HandleEndOfInput() = 0; + virtual void SetNextOperation(IOperation* operation) = 0; + virtual ~IOperation() { + if(next_operation_){ + delete next_operation_; + } + } + IOperation* next_operation_; +}; + +class EchoOperation : public IOperation { +public: + EchoOperation() : IOperation(nullptr) {} + EchoOperation(std::string& str, IOperation* operation = nullptr) : IOperation(operation), str_(str) {} + + void ProcessLine(const std::string& str) override { + std::cout << str << std::endl; + } + + void HandleEndOfInput() override { + ProcessLine(str_); + if(next_operation_) { + next_operation_->HandleEndOfInput(); + } + } + + void SetNextOperation(IOperation* operation) override { + next_operation_ = operation; + } + +private: + std::string str_; +}; + + +class CatOperation : public IOperation { +public: + CatOperation() : IOperation(nullptr) {} + CatOperation(std::string& filename, IOperation* next_operation = nullptr) : IOperation(next_operation), filename_(filename) {} + + void ProcessLine(const std::string& str) override { + std::ifstream file_(str); + if (!file_.is_open()) { + throw std::runtime_error("Cannot open file: " + str); + } + // читаем строки из файла и выводим их + std::string line; + while (std::getline(file_, line)) { + std::cout << line << std::endl; + } + } + + void HandleEndOfInput() override { + ProcessLine(filename_); + if (next_operation_) { + next_operation_->HandleEndOfInput(); + } + } + + void SetNextOperation(IOperation* operation) override { + next_operation_ = operation; + } + +private: + std::string filename_; +}; + +class OperationsList { +public: + OperationsList() : head_(nullptr), tail_(nullptr) {} + + void AddOperation(IOperation* op) { + if (!head_) { + head_ = op; + tail_ = op; + } else { + tail_->SetNextOperation(op); + tail_ = op; + } + } + + void RunOperations() { + if (head_) { + head_->HandleEndOfInput(); + } + } + + virtual ~OperationsList() { + IOperation* cur = head_; + IOperation* prev; + while (cur) { + prev = cur; + cur = cur->next_operation_; + delete prev; + } + } + +private: + IOperation* head_; + IOperation* tail_; +}; \ No newline at end of file diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/IOperation.cpp b/src/IOperation.cpp deleted file mode 100644 index b8635aa..0000000 --- a/src/IOperation.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include "IOperation.hpp" - -class IOperation { -public: - virtual void ProcessLine(const std::string& str) = 0; - virtual void HandleEndOfInput() = 0; - virtual void SetNextOperation(IOperation* operation) = 0; - virtual ~IOperation() {} -}; - - -class EchoOperation : public IOperation { -public: - EchoOperation() : next_operation_(nullptr) {} - EchoOperation(const std::string& str, IOperation* operation = nullptr) : str_(str), next_operation_(operation) {} - - void ProcessLine(const std::string& str) override { - std::cout << str << std::endl; - } - - void HandleEndOfInput() override { - ProcessLine(str_); - if(next_operation_) { - next_operation_->HandleEndOfInput(); - } - } - - void SetNextOperation(IOperation* operation) override { - next_operation_ = operation; - } -private: - const std::string& str_; - IOperation* next_operation_; -}; - - -class CatOperation : public IOperation { -public: - CatOperation() : file_(nullptr), next_operation_(nullptr) {} - CatOperation(const std::string file, IOperation* next_operation=nullptr) : file_(file), next_operation_(next_operation) {} - - void ProcessLine(const std::string& str) override { - if (!file_.is_open()) { - std::cerr << "Cannot open file: " << str << std::endl; - HandleEndOfInput(); - } - // читаем строки из файла и выводим их - std::string line; - while (std::getline(file_, line)) { - std::cout << line << std::endl; - } - HandleEndOfInput(); - } - - void HandleEndOfInput() override { - if (next_operation_) { - next_operation_->HandleEndOfInput(); - } - } - - void SetNextOperation(IOperation* operation) override { - next_operation_ = operation; - } - - ~CatOperation() { - std::cout << "Destructor CatOperation\n"; - if(next_operation_) { - delete next_operation_; - } - } - -private: - std::ifstream file_; - IOperation* next_operation_; -}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8abc6f0..85213d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,42 @@ #include +#include +#include +#include #include "IOperation.hpp" + int main() { - std::cout << "Hello Easy C++ project!" << std::endl; - print(); + std::string input = "echo million$ | cat static/text.txt | cat static/zarplata.txt"; + + OperationsList list; + + std::string delimiter = " | "; + size_t pos = 0; + std::string token; + while ((pos = input.find(delimiter)) != std::string::npos) { + token = input.substr(0, pos); + input.erase(0, pos + delimiter.length()); + + if (token.find("echo") == 0) { + std::string str = token.substr(5); + list.AddOperation(new EchoOperation(str)); + } else if (token.find("cat") == 0) { + std::string file = token.substr(4); + list.AddOperation(new CatOperation(file)); + } + } + + if (!input.empty()) { + if (input.find("echo") == 0) { + std::string str = input.substr(5); + list.AddOperation(new EchoOperation(str)); + } else if (input.find("cat") == 0) { + std::string file = input.substr(4); + list.AddOperation(new CatOperation(file)); + } + } + + list.RunOperations(); + + return 0; } \ No newline at end of file From a54d6a0aeeb40b0b6e3efd80d6e1d500be4698b2 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 29 Mar 2023 21:23:12 +0300 Subject: [PATCH 06/15] Stable v1 --- Makefile | 3 +- include/CommandParser.hpp | 16 +++++++++++ include/IOperation.hpp | 44 +++-------------------------- src/CommandParser.cpp | 58 +++++++++++++++++++++++++++++++++++++++ src/main.cpp | 41 +++++---------------------- 5 files changed, 86 insertions(+), 76 deletions(-) diff --git a/Makefile b/Makefile index b538a56..fd3e170 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,7 @@ EXECUTABLE := main all: $(BIN)/$(EXECUTABLE) run: clean all - clear - ./$(BIN)/$(EXECUTABLE) 'echo million$ | cat text.txt | cat zarplata.txt' + ./$(BIN)/$(EXECUTABLE) 'echo million | cat static/text.txt | cat static/zarplata.txt' $(BIN)/$(EXECUTABLE): $(SRC)/*.cpp $(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index 7b53e08..b308ecd 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -1,3 +1,19 @@ #pragma once #include +#include "IOperation.hpp" +class OperationsList { +public: + OperationsList() : head_(nullptr), tail_(nullptr) {} + OperationsList(std::string input); + + void AddOperation(IOperation* op); + void RunOperations(); + + virtual ~OperationsList(); + +private: + std::string delimiter = " | "; + IOperation* head_; + IOperation* tail_; +}; \ No newline at end of file diff --git a/include/IOperation.hpp b/include/IOperation.hpp index e699279..4cfbcd4 100644 --- a/include/IOperation.hpp +++ b/include/IOperation.hpp @@ -6,14 +6,13 @@ class IOperation { public: IOperation() : next_operation_(nullptr) {} IOperation(IOperation * op) : next_operation_(op) {} + virtual void ProcessLine(const std::string& str) = 0; virtual void HandleEndOfInput() = 0; virtual void SetNextOperation(IOperation* operation) = 0; - virtual ~IOperation() { - if(next_operation_){ - delete next_operation_; - } - } + + virtual ~IOperation() {} + IOperation* next_operation_; }; @@ -72,39 +71,4 @@ class CatOperation : public IOperation { private: std::string filename_; -}; - -class OperationsList { -public: - OperationsList() : head_(nullptr), tail_(nullptr) {} - - void AddOperation(IOperation* op) { - if (!head_) { - head_ = op; - tail_ = op; - } else { - tail_->SetNextOperation(op); - tail_ = op; - } - } - - void RunOperations() { - if (head_) { - head_->HandleEndOfInput(); - } - } - - virtual ~OperationsList() { - IOperation* cur = head_; - IOperation* prev; - while (cur) { - prev = cur; - cur = cur->next_operation_; - delete prev; - } - } - -private: - IOperation* head_; - IOperation* tail_; }; \ No newline at end of file diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index e69de29..90b5cdc 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -0,0 +1,58 @@ +#include "CommandParser.hpp" + +OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullptr) { + size_t pos = 0; + std::string token; + + while ((pos = input.find(delimiter)) != std::string::npos) { + token = input.substr(0, pos); + input.erase(0, pos + delimiter.length()); + + if (token.find("echo") == 0) { + std::string str = token.substr(5); + AddOperation(new EchoOperation(str)); + } else if (token.find("cat") == 0) { + std::string file = token.substr(4); + AddOperation(new CatOperation(file)); + } + } + + if (!input.empty()) { + if (input.find("echo") == 0) { + std::string str = input.substr(5); + AddOperation(new EchoOperation(str)); + } else if (input.find("cat") == 0) { + std::string file = input.substr(4); + AddOperation(new CatOperation(file)); + } + } +} + + +void OperationsList::AddOperation(IOperation* op) { + if (!head_) { + head_ = op; + tail_ = op; + } else { + tail_->SetNextOperation(op); + tail_ = op; + } +} + + +void OperationsList::RunOperations() { + if (head_) { + head_->HandleEndOfInput(); + } +} + + +OperationsList::~OperationsList() { + IOperation* cur = head_; + IOperation* next; + while (cur) { + next = cur->next_operation_; + delete cur; + cur = next; + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 85213d1..730f977 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,41 +1,14 @@ #include -#include -#include -#include -#include "IOperation.hpp" +#include "CommandParser.hpp" -int main() { - std::string input = "echo million$ | cat static/text.txt | cat static/zarplata.txt"; - - OperationsList list; - - std::string delimiter = " | "; - size_t pos = 0; - std::string token; - while ((pos = input.find(delimiter)) != std::string::npos) { - token = input.substr(0, pos); - input.erase(0, pos + delimiter.length()); - - if (token.find("echo") == 0) { - std::string str = token.substr(5); - list.AddOperation(new EchoOperation(str)); - } else if (token.find("cat") == 0) { - std::string file = token.substr(4); - list.AddOperation(new CatOperation(file)); - } +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Run program with arguments like: 'echo | cat | echo million | cat Elon.txt'\n"; + return 1; } - - if (!input.empty()) { - if (input.find("echo") == 0) { - std::string str = input.substr(5); - list.AddOperation(new EchoOperation(str)); - } else if (input.find("cat") == 0) { - std::string file = input.substr(4); - list.AddOperation(new CatOperation(file)); - } - } - + + OperationsList list(argv[1]); list.RunOperations(); return 0; From 80fd8224f9045307f339d483ef323b15516860f6 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 29 Mar 2023 21:45:02 +0300 Subject: [PATCH 07/15] Some comments --- include/CommandParser.hpp | 1 + src/CommandParser.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index b308ecd..d98b6cb 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -5,6 +5,7 @@ class OperationsList { public: OperationsList() : head_(nullptr), tail_(nullptr) {} + // input копируем, так как в далньейшем в функции он будет меняться OperationsList(std::string input); void AddOperation(IOperation* op); diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 90b5cdc..feeee44 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -4,19 +4,23 @@ OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullpt size_t pos = 0; std::string token; + // Пока есть разделители, запоминаем позицию while ((pos = input.find(delimiter)) != std::string::npos) { + // Получаем подстроку до разделителя token = input.substr(0, pos); + // Удаляем ее из input учитывая длину разделителя input.erase(0, pos + delimiter.length()); if (token.find("echo") == 0) { - std::string str = token.substr(5); + std::string str = token.substr(5); // Достаем переданную строку AddOperation(new EchoOperation(str)); } else if (token.find("cat") == 0) { - std::string file = token.substr(4); + std::string file = token.substr(4); // Достаем переданный файл AddOperation(new CatOperation(file)); } } + // Последняя команда указана без разделителя, обрабатываем ее if (!input.empty()) { if (input.find("echo") == 0) { std::string str = input.substr(5); From 24c5feb2e6d679dddce745d94c013a5c6beed5e9 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Sun, 2 Apr 2023 10:34:04 +0300 Subject: [PATCH 08/15] move logic hpp to IOperation.cpp --- include/IOperation.hpp | 41 +++++------------------------------------ src/IOperation.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 36 deletions(-) create mode 100644 src/IOperation.cpp diff --git a/include/IOperation.hpp b/include/IOperation.hpp index 4cfbcd4..de52995 100644 --- a/include/IOperation.hpp +++ b/include/IOperation.hpp @@ -9,7 +9,7 @@ class IOperation { virtual void ProcessLine(const std::string& str) = 0; virtual void HandleEndOfInput() = 0; - virtual void SetNextOperation(IOperation* operation) = 0; + virtual void SetNextOperation(IOperation* operation); virtual ~IOperation() {} @@ -21,20 +21,8 @@ class EchoOperation : public IOperation { EchoOperation() : IOperation(nullptr) {} EchoOperation(std::string& str, IOperation* operation = nullptr) : IOperation(operation), str_(str) {} - void ProcessLine(const std::string& str) override { - std::cout << str << std::endl; - } - - void HandleEndOfInput() override { - ProcessLine(str_); - if(next_operation_) { - next_operation_->HandleEndOfInput(); - } - } - - void SetNextOperation(IOperation* operation) override { - next_operation_ = operation; - } + void ProcessLine(const std::string& str) override; + void HandleEndOfInput() override; private: std::string str_; @@ -46,28 +34,9 @@ class CatOperation : public IOperation { CatOperation() : IOperation(nullptr) {} CatOperation(std::string& filename, IOperation* next_operation = nullptr) : IOperation(next_operation), filename_(filename) {} - void ProcessLine(const std::string& str) override { - std::ifstream file_(str); - if (!file_.is_open()) { - throw std::runtime_error("Cannot open file: " + str); - } - // читаем строки из файла и выводим их - std::string line; - while (std::getline(file_, line)) { - std::cout << line << std::endl; - } - } - - void HandleEndOfInput() override { - ProcessLine(filename_); - if (next_operation_) { - next_operation_->HandleEndOfInput(); - } - } + void ProcessLine(const std::string& str) override; - void SetNextOperation(IOperation* operation) override { - next_operation_ = operation; - } + void HandleEndOfInput() override; private: std::string filename_; diff --git a/src/IOperation.cpp b/src/IOperation.cpp new file mode 100644 index 0000000..8a78822 --- /dev/null +++ b/src/IOperation.cpp @@ -0,0 +1,40 @@ +#include "IOperation.hpp" + +// Реализуем по умолчанию метод интерфейсного класса +void IOperation::SetNextOperation(IOperation* operation) { + next_operation_ = operation; +} + + +void EchoOperation::ProcessLine(const std::string& str) { + std::cout << str << std::endl; +} + + +void EchoOperation::HandleEndOfInput() { + ProcessLine(str_); + if(next_operation_) { + next_operation_->HandleEndOfInput(); + } +} + + +void CatOperation::ProcessLine(const std::string& str) { + std::ifstream file_(str); + if (!file_.is_open()) { + throw std::runtime_error("Cannot open file: " + str); + } + // читаем строки из файла и выводим их + std::string line; + while (std::getline(file_, line)) { + std::cout << line << std::endl; + } +} + + +void CatOperation::HandleEndOfInput() { + ProcessLine(filename_); + if (next_operation_) { + next_operation_->HandleEndOfInput(); + } +} \ No newline at end of file From f622997d6793745236704a3948c127f859963d29 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Mon, 3 Apr 2023 15:14:48 +0300 Subject: [PATCH 09/15] Each class in own hpp & shared ptrs --- include/CatOperation.hpp | 17 +++++++++++++++++ include/CommandParser.hpp | 15 ++++++++------- include/EchoOperation.hpp | 16 ++++++++++++++++ include/IOperation.hpp | 36 +++++------------------------------- src/CatOperation.cpp | 21 +++++++++++++++++++++ src/CommandParser.cpp | 29 +++++++++-------------------- src/EchoOperation.cpp | 13 +++++++++++++ src/IOperation.cpp | 38 ++------------------------------------ src/main.cpp | 9 +++++++-- 9 files changed, 98 insertions(+), 96 deletions(-) create mode 100644 include/CatOperation.hpp create mode 100644 include/EchoOperation.hpp create mode 100644 src/CatOperation.cpp create mode 100644 src/EchoOperation.cpp diff --git a/include/CatOperation.hpp b/include/CatOperation.hpp new file mode 100644 index 0000000..0bb5e95 --- /dev/null +++ b/include/CatOperation.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +#include "IOperation.hpp" + +class CatOperation : public IOperation { +public: + CatOperation() : IOperation() {} + CatOperation(std::string& filename, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), filename_(filename) {} + + void ProcessLine(const std::string& str) override; + void HandleEndOfInput() override; + +private: + std::string filename_; +}; \ No newline at end of file diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index d98b6cb..c8b43a6 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -1,20 +1,21 @@ #pragma once #include +#include #include "IOperation.hpp" +#include "EchoOperation.hpp" +#include "CatOperation.hpp" class OperationsList { public: - OperationsList() : head_(nullptr), tail_(nullptr) {} + OperationsList() : head_(), tail_() {} // input копируем, так как в далньейшем в функции он будет меняться OperationsList(std::string input); - void AddOperation(IOperation* op); + void AddOperation(std::shared_ptr&& operation); void RunOperations(); - virtual ~OperationsList(); - private: - std::string delimiter = " | "; - IOperation* head_; - IOperation* tail_; + const std::string delimiter = " | "; + std::shared_ptr head_; + std::shared_ptr tail_; }; \ No newline at end of file diff --git a/include/EchoOperation.hpp b/include/EchoOperation.hpp new file mode 100644 index 0000000..f2f0138 --- /dev/null +++ b/include/EchoOperation.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include +#include "IOperation.hpp" + +class EchoOperation : public IOperation { +public: + EchoOperation() : IOperation() {} + EchoOperation(std::string& str, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), str_(str) {} + + void ProcessLine(const std::string& str) override; + void HandleEndOfInput() override; + +private: + std::string str_; +}; \ No newline at end of file diff --git a/include/IOperation.hpp b/include/IOperation.hpp index de52995..c646f24 100644 --- a/include/IOperation.hpp +++ b/include/IOperation.hpp @@ -1,43 +1,17 @@ #pragma once #include -#include +#include class IOperation { public: - IOperation() : next_operation_(nullptr) {} - IOperation(IOperation * op) : next_operation_(op) {} + IOperation() : next_operation_() {} + IOperation(std::shared_ptr&& operation) : next_operation_(std::move(operation)) {} virtual void ProcessLine(const std::string& str) = 0; virtual void HandleEndOfInput() = 0; - virtual void SetNextOperation(IOperation* operation); + virtual void SetNextOperation(std::shared_ptr&& operation); virtual ~IOperation() {} - IOperation* next_operation_; -}; - -class EchoOperation : public IOperation { -public: - EchoOperation() : IOperation(nullptr) {} - EchoOperation(std::string& str, IOperation* operation = nullptr) : IOperation(operation), str_(str) {} - - void ProcessLine(const std::string& str) override; - void HandleEndOfInput() override; - -private: - std::string str_; -}; - - -class CatOperation : public IOperation { -public: - CatOperation() : IOperation(nullptr) {} - CatOperation(std::string& filename, IOperation* next_operation = nullptr) : IOperation(next_operation), filename_(filename) {} - - void ProcessLine(const std::string& str) override; - - void HandleEndOfInput() override; - -private: - std::string filename_; + std::shared_ptr next_operation_; }; \ No newline at end of file diff --git a/src/CatOperation.cpp b/src/CatOperation.cpp new file mode 100644 index 0000000..07ef7bf --- /dev/null +++ b/src/CatOperation.cpp @@ -0,0 +1,21 @@ +#include "CatOperation.hpp" + +void CatOperation::ProcessLine(const std::string& str) { + std::ifstream file_(str); + if (!file_.is_open()) { + throw std::runtime_error("Cannot open file: " + str); + } + // читаем строки из файла и выводим их + std::string line; + while (std::getline(file_, line)) { + std::cout << line << std::endl; + } +} + + +void CatOperation::HandleEndOfInput() { + ProcessLine(filename_); + if (next_operation_) { + next_operation_->HandleEndOfInput(); + } +} \ No newline at end of file diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index feeee44..1406127 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -13,10 +13,10 @@ OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullpt if (token.find("echo") == 0) { std::string str = token.substr(5); // Достаем переданную строку - AddOperation(new EchoOperation(str)); + AddOperation(std::make_shared(str)); } else if (token.find("cat") == 0) { std::string file = token.substr(4); // Достаем переданный файл - AddOperation(new CatOperation(file)); + AddOperation(std::make_shared(file)); } } @@ -24,22 +24,22 @@ OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullpt if (!input.empty()) { if (input.find("echo") == 0) { std::string str = input.substr(5); - AddOperation(new EchoOperation(str)); + AddOperation(std::make_shared(str)); } else if (input.find("cat") == 0) { std::string file = input.substr(4); - AddOperation(new CatOperation(file)); + AddOperation(std::make_shared(file)); } } } -void OperationsList::AddOperation(IOperation* op) { +void OperationsList::AddOperation(std::shared_ptr&& operation) { if (!head_) { - head_ = op; - tail_ = op; + head_ = std::move(operation); + tail_ = head_; } else { - tail_->SetNextOperation(op); - tail_ = op; + tail_->SetNextOperation(std::move(operation)); + tail_ = tail_->next_operation_; } } @@ -48,15 +48,4 @@ void OperationsList::RunOperations() { if (head_) { head_->HandleEndOfInput(); } -} - - -OperationsList::~OperationsList() { - IOperation* cur = head_; - IOperation* next; - while (cur) { - next = cur->next_operation_; - delete cur; - cur = next; - } } \ No newline at end of file diff --git a/src/EchoOperation.cpp b/src/EchoOperation.cpp new file mode 100644 index 0000000..101d004 --- /dev/null +++ b/src/EchoOperation.cpp @@ -0,0 +1,13 @@ +#include "EchoOperation.hpp" + +void EchoOperation::ProcessLine(const std::string& str) { + std::cout << str << std::endl; +} + + +void EchoOperation::HandleEndOfInput() { + ProcessLine(str_); + if(next_operation_) { + next_operation_->HandleEndOfInput(); + } +} \ No newline at end of file diff --git a/src/IOperation.cpp b/src/IOperation.cpp index 8a78822..319a16a 100644 --- a/src/IOperation.cpp +++ b/src/IOperation.cpp @@ -1,40 +1,6 @@ #include "IOperation.hpp" // Реализуем по умолчанию метод интерфейсного класса -void IOperation::SetNextOperation(IOperation* operation) { - next_operation_ = operation; -} - - -void EchoOperation::ProcessLine(const std::string& str) { - std::cout << str << std::endl; -} - - -void EchoOperation::HandleEndOfInput() { - ProcessLine(str_); - if(next_operation_) { - next_operation_->HandleEndOfInput(); - } -} - - -void CatOperation::ProcessLine(const std::string& str) { - std::ifstream file_(str); - if (!file_.is_open()) { - throw std::runtime_error("Cannot open file: " + str); - } - // читаем строки из файла и выводим их - std::string line; - while (std::getline(file_, line)) { - std::cout << line << std::endl; - } -} - - -void CatOperation::HandleEndOfInput() { - ProcessLine(filename_); - if (next_operation_) { - next_operation_->HandleEndOfInput(); - } +void IOperation::SetNextOperation(std::shared_ptr&& operation) { + next_operation_ = std::move(operation); } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 730f977..46e967d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,9 +7,14 @@ int main(int argc, char* argv[]) { std::cerr << "Run program with arguments like: 'echo | cat | echo million | cat Elon.txt'\n"; return 1; } + try{ + OperationsList list(argv[1]); + list.RunOperations(); + } + catch(const std::exception& e){ + std::cerr << e.what() << '\n'; + } - OperationsList list(argv[1]); - list.RunOperations(); return 0; } \ No newline at end of file From b8ce53743426ccc83a0ac12e3e98d330b8f2d925 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Mon, 3 Apr 2023 15:47:48 +0300 Subject: [PATCH 10/15] Some factroing --- include/CommandParser.hpp | 1 + src/CommandParser.cpp | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index c8b43a6..04af833 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -12,6 +12,7 @@ class OperationsList { OperationsList(std::string input); void AddOperation(std::shared_ptr&& operation); + void AddOperation(const std::string token); void RunOperations(); private: diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 1406127..109456b 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -3,32 +3,32 @@ OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullptr) { size_t pos = 0; std::string token; - + // Пока есть разделители, запоминаем позицию while ((pos = input.find(delimiter)) != std::string::npos) { // Получаем подстроку до разделителя token = input.substr(0, pos); // Удаляем ее из input учитывая длину разделителя - input.erase(0, pos + delimiter.length()); - - if (token.find("echo") == 0) { - std::string str = token.substr(5); // Достаем переданную строку - AddOperation(std::make_shared(str)); - } else if (token.find("cat") == 0) { - std::string file = token.substr(4); // Достаем переданный файл - AddOperation(std::make_shared(file)); - } + input = input.substr(pos + delimiter.length()); + AddOperation(token); } // Последняя команда указана без разделителя, обрабатываем ее if (!input.empty()) { - if (input.find("echo") == 0) { - std::string str = input.substr(5); - AddOperation(std::make_shared(str)); - } else if (input.find("cat") == 0) { - std::string file = input.substr(4); - AddOperation(std::make_shared(file)); - } + AddOperation(input); + } +} + +void OperationsList::AddOperation(const std::string token){ + const std::string ECHO = "echo"; + const std::string CAT = "cat"; + + if (token.find(ECHO) == 0) { + std::string str = token.substr(ECHO.length() + 1); // Достаем переданную строку + AddOperation(std::make_shared(str)); + } else if (token.find(CAT) == 0) { + std::string file = token.substr(CAT.length() + 1); // Достаем переданный файл + AddOperation(std::make_shared(file)); } } From 2ad924dd0b35a91397ca6a0852ecc23eb0bf2458 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Mon, 3 Apr 2023 15:49:49 +0300 Subject: [PATCH 11/15] adding string_view --- include/CommandParser.hpp | 5 +++-- src/CommandParser.cpp | 17 +++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index 04af833..ddc70ae 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "IOperation.hpp" #include "EchoOperation.hpp" #include "CatOperation.hpp" @@ -9,10 +10,10 @@ class OperationsList { public: OperationsList() : head_(), tail_() {} // input копируем, так как в далньейшем в функции он будет меняться - OperationsList(std::string input); + OperationsList(const std::string& input); void AddOperation(std::shared_ptr&& operation); - void AddOperation(const std::string token); + void AddOperation(const std::string& token); void RunOperations(); private: diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 109456b..2c69756 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -1,25 +1,26 @@ #include "CommandParser.hpp" -OperationsList::OperationsList(std::string input) : head_(nullptr), tail_(nullptr) { +OperationsList::OperationsList(const std::string& input) : head_(nullptr), tail_(nullptr) { size_t pos = 0; std::string token; - + std::string_view cursor(input); + // Пока есть разделители, запоминаем позицию - while ((pos = input.find(delimiter)) != std::string::npos) { + while ((pos = cursor.find(delimiter)) != std::string::npos) { // Получаем подстроку до разделителя - token = input.substr(0, pos); + token = cursor.substr(0, pos); // Удаляем ее из input учитывая длину разделителя - input = input.substr(pos + delimiter.length()); + cursor = cursor.substr(pos + delimiter.length()); AddOperation(token); } // Последняя команда указана без разделителя, обрабатываем ее - if (!input.empty()) { - AddOperation(input); + if (!cursor.empty()) { + AddOperation(std::string(cursor)); } } -void OperationsList::AddOperation(const std::string token){ +void OperationsList::AddOperation(const std::string& token){ const std::string ECHO = "echo"; const std::string CAT = "cat"; From b2b615ca1f5093c8afc37b7af392344db777a2b5 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 5 Apr 2023 21:47:24 +0300 Subject: [PATCH 12/15] CMake, final, C++20 --- CMakeLists.txt | 25 +++++++++++++++++++++++++ Makefile | 21 ++++++++++----------- include/CatOperation.hpp | 2 +- include/EchoOperation.hpp | 2 +- src/CommandParser.cpp | 6 +++--- 5 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c4a43e3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.15) +project(CommandParser) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +file(GLOB SOURCES "src/*.cpp") + +# add_custom_target(run COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE} 'echo million | cat static/text.txt | cat static/zarplata.txt') +# MakeFile удобнее, так как там я мог make run сразу запускать файл с переданной строкой + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) + +target_link_libraries(${PROJECT_NAME}) + + +# Автоматический запуск тестов после сборки +add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure +) diff --git a/Makefile b/Makefile index fd3e170..b0ecccd 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,21 @@ -CXX := g++ -CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb +CXX := g++ +CXX_FLAGS := -Wall -Wextra -std=c++20 -ggdb -BIN := bin -SRC := src -INCLUDE := include -LIB := lib - -LIBRARIES := -EXECUTABLE := main +BIN := bin +SRC := src +INCLUDE := include +LIB := lib +LIBRARIES := +EXECUTABLE := main all: $(BIN)/$(EXECUTABLE) run: clean all ./$(BIN)/$(EXECUTABLE) 'echo million | cat static/text.txt | cat static/zarplata.txt' -$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp +$(BIN)/$(EXECUTABLE): $(wildcard $(SRC)/*.cpp) $(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) clean: - -rm $(BIN)/* + -rm -f $(BIN)/* \ No newline at end of file diff --git a/include/CatOperation.hpp b/include/CatOperation.hpp index 0bb5e95..38f312f 100644 --- a/include/CatOperation.hpp +++ b/include/CatOperation.hpp @@ -4,7 +4,7 @@ #include #include "IOperation.hpp" -class CatOperation : public IOperation { +class CatOperation final : public IOperation { public: CatOperation() : IOperation() {} CatOperation(std::string& filename, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), filename_(filename) {} diff --git a/include/EchoOperation.hpp b/include/EchoOperation.hpp index f2f0138..c03b712 100644 --- a/include/EchoOperation.hpp +++ b/include/EchoOperation.hpp @@ -3,7 +3,7 @@ #include #include "IOperation.hpp" -class EchoOperation : public IOperation { +class EchoOperation final : public IOperation { public: EchoOperation() : IOperation() {} EchoOperation(std::string& str, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), str_(str) {} diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 2c69756..453d9c2 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -23,11 +23,11 @@ OperationsList::OperationsList(const std::string& input) : head_(nullptr), tail_ void OperationsList::AddOperation(const std::string& token){ const std::string ECHO = "echo"; const std::string CAT = "cat"; - - if (token.find(ECHO) == 0) { + + if (token.starts_with(ECHO)) { std::string str = token.substr(ECHO.length() + 1); // Достаем переданную строку AddOperation(std::make_shared(str)); - } else if (token.find(CAT) == 0) { + } else if (token.starts_with(CAT)) { std::string file = token.substr(CAT.length() + 1); // Достаем переданный файл AddOperation(std::make_shared(file)); } From fc2ddb162c07c1f30851f3d320e8e9dda70ece01 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 5 Apr 2023 22:29:35 +0300 Subject: [PATCH 13/15] wc -c Operation --- CMakeLists.txt | 2 +- Makefile | 2 +- include/CommandParser.hpp | 5 ++++- include/WcOperation.hpp | 18 ++++++++++++++++++ src/CommandParser.cpp | 13 +++++++++---- src/WcOperation.cpp | 25 +++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 include/WcOperation.hpp create mode 100644 src/WcOperation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c4a43e3..0cd353c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) file(GLOB SOURCES "src/*.cpp") -# add_custom_target(run COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE} 'echo million | cat static/text.txt | cat static/zarplata.txt') +# add_custom_target(run COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE} 'echo million | cat ../static/text.txt | cat ../static/zarplata.txt | wc -c | echo rambler | cat ../static/zarplata.txt | wc -c | cat ../static/text.txt | wc -c') # MakeFile удобнее, так как там я мог make run сразу запускать файл с переданной строкой add_executable(${PROJECT_NAME} ${SOURCES}) diff --git a/Makefile b/Makefile index b0ecccd..eccd7bc 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ EXECUTABLE := main all: $(BIN)/$(EXECUTABLE) run: clean all - ./$(BIN)/$(EXECUTABLE) 'echo million | cat static/text.txt | cat static/zarplata.txt' + ./$(BIN)/$(EXECUTABLE) 'echo million | cat static/text.txt | cat static/zarplata.txt | wc -c | echo rambler | cat static/zarplata.txt | wc -c | cat static/text.txt | wc -c' $(BIN)/$(EXECUTABLE): $(wildcard $(SRC)/*.cpp) $(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index ddc70ae..ece0d73 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -5,10 +5,11 @@ #include "IOperation.hpp" #include "EchoOperation.hpp" #include "CatOperation.hpp" +#include "WcOperation.hpp" class OperationsList { public: - OperationsList() : head_(), tail_() {} + OperationsList() : pipeline_(), fileNames_(), head_(), tail_() {} // input копируем, так как в далньейшем в функции он будет меняться OperationsList(const std::string& input); @@ -17,6 +18,8 @@ class OperationsList { void RunOperations(); private: + const std::string pipeline_; + std::string fileNames_; const std::string delimiter = " | "; std::shared_ptr head_; std::shared_ptr tail_; diff --git a/include/WcOperation.hpp b/include/WcOperation.hpp new file mode 100644 index 0000000..81b1c1a --- /dev/null +++ b/include/WcOperation.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include +#include "IOperation.hpp" + +class WcOperation final : public IOperation { +public: + WcOperation() : IOperation() {} + WcOperation(std::string& pipeline, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), pipeline_(pipeline) {} + + void ProcessLine(const std::string& str) override; + void HandleEndOfInput() override; + +private: + std::string pipeline_; +}; \ No newline at end of file diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 453d9c2..68132b1 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -1,15 +1,15 @@ #include "CommandParser.hpp" -OperationsList::OperationsList(const std::string& input) : head_(nullptr), tail_(nullptr) { +OperationsList::OperationsList(const std::string& input) : pipeline_(input), head_(nullptr), tail_(nullptr) { size_t pos = 0; std::string token; - std::string_view cursor(input); + std::string_view cursor(pipeline_); // Пока есть разделители, запоминаем позицию while ((pos = cursor.find(delimiter)) != std::string::npos) { // Получаем подстроку до разделителя token = cursor.substr(0, pos); - // Удаляем ее из input учитывая длину разделителя + // Удаляем ее из pipeline_ учитывая длину разделителя cursor = cursor.substr(pos + delimiter.length()); AddOperation(token); } @@ -23,13 +23,18 @@ OperationsList::OperationsList(const std::string& input) : head_(nullptr), tail_ void OperationsList::AddOperation(const std::string& token){ const std::string ECHO = "echo"; const std::string CAT = "cat"; - + const std::string WC = "wc -c"; + if (token.starts_with(ECHO)) { std::string str = token.substr(ECHO.length() + 1); // Достаем переданную строку AddOperation(std::make_shared(str)); } else if (token.starts_with(CAT)) { std::string file = token.substr(CAT.length() + 1); // Достаем переданный файл + fileNames_ += file + " "; AddOperation(std::make_shared(file)); + } else if (token == WC) { + AddOperation(std::make_shared(fileNames_)); + fileNames_ = ""; } } diff --git a/src/WcOperation.cpp b/src/WcOperation.cpp new file mode 100644 index 0000000..57c6fe4 --- /dev/null +++ b/src/WcOperation.cpp @@ -0,0 +1,25 @@ +#include "WcOperation.hpp" + +void WcOperation::ProcessLine(const std::string& str) { + // str всегда вида "file1.txt file2.txt file3.txt " или "" + std::istringstream iss(str); + std::string filename; + int bytes = 0; + while (iss >> filename) { // Читаем имена файлов из потока + std::ifstream file(filename, std::ios::binary); + if (file) { // Проверяем, успешно ли открылся файл + file.seekg(0, std::ios::end); + bytes += file.tellg(); + } + } + // Выводим результат в стандартный поток вывода + std::cout << "Total bytes: " << bytes << std::endl; +} + + +void WcOperation::HandleEndOfInput() { + ProcessLine(pipeline_); + if (next_operation_) { + next_operation_->HandleEndOfInput(); + } +} \ No newline at end of file From 74104b39d42c6dc5f0039e4a59ed45b578851170 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Wed, 5 Apr 2023 22:32:27 +0300 Subject: [PATCH 14/15] some clean code --- src/WcOperation.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/WcOperation.cpp b/src/WcOperation.cpp index 57c6fe4..0999c28 100644 --- a/src/WcOperation.cpp +++ b/src/WcOperation.cpp @@ -7,10 +7,12 @@ void WcOperation::ProcessLine(const std::string& str) { int bytes = 0; while (iss >> filename) { // Читаем имена файлов из потока std::ifstream file(filename, std::ios::binary); - if (file) { // Проверяем, успешно ли открылся файл - file.seekg(0, std::ios::end); - bytes += file.tellg(); + if (!file.is_open()) { + throw std::runtime_error("Cannot open file: " + filename); } + + file.seekg(0, std::ios::end); + bytes += file.tellg(); } // Выводим результат в стандартный поток вывода std::cout << "Total bytes: " << bytes << std::endl; From 77429af86d18b2fac042839e355c512283914eb6 Mon Sep 17 00:00:00 2001 From: TimofeyTst Date: Fri, 21 Apr 2023 12:46:14 +0300 Subject: [PATCH 15/15] Version 3.0 Sending prev pipeline to next operation --- include/CatOperation.hpp | 2 +- include/CommandParser.hpp | 3 +-- include/EchoOperation.hpp | 2 +- include/IOperation.hpp | 2 +- include/WcOperation.hpp | 6 +++--- src/CatOperation.cpp | 29 ++++++++++++++++++----------- src/CommandParser.cpp | 19 ++++++++++++++----- src/EchoOperation.cpp | 13 +++++++------ src/WcOperation.cpp | 27 +++++++++------------------ 9 files changed, 55 insertions(+), 48 deletions(-) diff --git a/include/CatOperation.hpp b/include/CatOperation.hpp index 38f312f..afb8036 100644 --- a/include/CatOperation.hpp +++ b/include/CatOperation.hpp @@ -9,7 +9,7 @@ class CatOperation final : public IOperation { CatOperation() : IOperation() {} CatOperation(std::string& filename, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), filename_(filename) {} - void ProcessLine(const std::string& str) override; + void ProcessLine(const std::string& pipeline) override; void HandleEndOfInput() override; private: diff --git a/include/CommandParser.hpp b/include/CommandParser.hpp index ece0d73..7d35347 100644 --- a/include/CommandParser.hpp +++ b/include/CommandParser.hpp @@ -9,7 +9,7 @@ class OperationsList { public: - OperationsList() : pipeline_(), fileNames_(), head_(), tail_() {} + OperationsList() : pipeline_(), head_(), tail_() {} // input копируем, так как в далньейшем в функции он будет меняться OperationsList(const std::string& input); @@ -19,7 +19,6 @@ class OperationsList { private: const std::string pipeline_; - std::string fileNames_; const std::string delimiter = " | "; std::shared_ptr head_; std::shared_ptr tail_; diff --git a/include/EchoOperation.hpp b/include/EchoOperation.hpp index c03b712..9ce6385 100644 --- a/include/EchoOperation.hpp +++ b/include/EchoOperation.hpp @@ -8,7 +8,7 @@ class EchoOperation final : public IOperation { EchoOperation() : IOperation() {} EchoOperation(std::string& str, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), str_(str) {} - void ProcessLine(const std::string& str) override; + void ProcessLine(const std::string& pipeline) override; void HandleEndOfInput() override; private: diff --git a/include/IOperation.hpp b/include/IOperation.hpp index c646f24..cdad323 100644 --- a/include/IOperation.hpp +++ b/include/IOperation.hpp @@ -7,7 +7,7 @@ class IOperation { IOperation() : next_operation_() {} IOperation(std::shared_ptr&& operation) : next_operation_(std::move(operation)) {} - virtual void ProcessLine(const std::string& str) = 0; + virtual void ProcessLine(const std::string& pipeline) = 0; virtual void HandleEndOfInput() = 0; virtual void SetNextOperation(std::shared_ptr&& operation); diff --git a/include/WcOperation.hpp b/include/WcOperation.hpp index 81b1c1a..01b6ee6 100644 --- a/include/WcOperation.hpp +++ b/include/WcOperation.hpp @@ -8,11 +8,11 @@ class WcOperation final : public IOperation { public: WcOperation() : IOperation() {} - WcOperation(std::string& pipeline, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), pipeline_(pipeline) {} + WcOperation(std::string& str, std::shared_ptr&& operation=nullptr) : IOperation(std::move(operation)), str_(str) {} - void ProcessLine(const std::string& str) override; + void ProcessLine(const std::string& pipeline) override; void HandleEndOfInput() override; private: - std::string pipeline_; + std::string str_; }; \ No newline at end of file diff --git a/src/CatOperation.cpp b/src/CatOperation.cpp index 07ef7bf..27d9c6c 100644 --- a/src/CatOperation.cpp +++ b/src/CatOperation.cpp @@ -1,21 +1,28 @@ #include "CatOperation.hpp" +#include -void CatOperation::ProcessLine(const std::string& str) { - std::ifstream file_(str); +void CatOperation::ProcessLine(const std::string& pipeline) { + std::ifstream file_(filename_); if (!file_.is_open()) { - throw std::runtime_error("Cannot open file: " + str); + throw std::runtime_error("Cannot open file: " + filename_); } - // читаем строки из файла и выводим их - std::string line; - while (std::getline(file_, line)) { - std::cout << line << std::endl; + + // создаем std::stringstream и передаем в него буфер файла + std::stringstream file_stream; + file_stream << file_.rdbuf(); + + // получаем содержимое файла в виде строки + std::string file_contents = file_stream.str(); + + // передаем pipeline + file_contents в метод ProcessLine следующей операции + if (next_operation_) { + next_operation_->ProcessLine(pipeline + file_contents); + } else { + std::cout << pipeline << std::endl << file_contents << std::endl; } } void CatOperation::HandleEndOfInput() { - ProcessLine(filename_); - if (next_operation_) { - next_operation_->HandleEndOfInput(); - } + ProcessLine(""); } \ No newline at end of file diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index 68132b1..53a614e 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -28,13 +28,22 @@ void OperationsList::AddOperation(const std::string& token){ if (token.starts_with(ECHO)) { std::string str = token.substr(ECHO.length() + 1); // Достаем переданную строку AddOperation(std::make_shared(str)); - } else if (token.starts_with(CAT)) { + return; + } + + if (token.starts_with(CAT)) { std::string file = token.substr(CAT.length() + 1); // Достаем переданный файл - fileNames_ += file + " "; AddOperation(std::make_shared(file)); - } else if (token == WC) { - AddOperation(std::make_shared(fileNames_)); - fileNames_ = ""; + return; + } + + if (token.starts_with(WC)) { + std::string str; + if (token.length() > WC.length()) { + str = token.substr(WC.length() + 1); // Достаем переданную строку + } + AddOperation(std::make_shared(str)); + return; } } diff --git a/src/EchoOperation.cpp b/src/EchoOperation.cpp index 101d004..07fdb66 100644 --- a/src/EchoOperation.cpp +++ b/src/EchoOperation.cpp @@ -1,13 +1,14 @@ #include "EchoOperation.hpp" -void EchoOperation::ProcessLine(const std::string& str) { - std::cout << str << std::endl; +void EchoOperation::ProcessLine(const std::string& pipeline) { + if(next_operation_) { + next_operation_->ProcessLine(str_); + } else { + std::cout << str_ << std::endl; + } } void EchoOperation::HandleEndOfInput() { - ProcessLine(str_); - if(next_operation_) { - next_operation_->HandleEndOfInput(); - } + ProcessLine(""); } \ No newline at end of file diff --git a/src/WcOperation.cpp b/src/WcOperation.cpp index 0999c28..4615ec9 100644 --- a/src/WcOperation.cpp +++ b/src/WcOperation.cpp @@ -1,27 +1,18 @@ #include "WcOperation.hpp" -void WcOperation::ProcessLine(const std::string& str) { - // str всегда вида "file1.txt file2.txt file3.txt " или "" - std::istringstream iss(str); - std::string filename; - int bytes = 0; - while (iss >> filename) { // Читаем имена файлов из потока - std::ifstream file(filename, std::ios::binary); - if (!file.is_open()) { - throw std::runtime_error("Cannot open file: " + filename); - } +void WcOperation::ProcessLine(const std::string& pipeline) { + // вычисляем суммарное число байт в строке full_string = pipeline + str_ + int total_bytes = sizeof(char) * (pipeline.size() + str_.size()); - file.seekg(0, std::ios::end); - bytes += file.tellg(); + // передаем pipeline + str_ в метод ProcessLine следующей операции + if (next_operation_) { + next_operation_->ProcessLine(std::to_string(total_bytes)); + } else { + std::cout << total_bytes << std::endl; } - // Выводим результат в стандартный поток вывода - std::cout << "Total bytes: " << bytes << std::endl; } void WcOperation::HandleEndOfInput() { - ProcessLine(pipeline_); - if (next_operation_) { - next_operation_->HandleEndOfInput(); - } + ProcessLine(""); } \ No newline at end of file