Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <Windows.h>
- //#include <vector>
- //#include <algorithm>
- //#include <iterator>
- #include <sstream>
- #include <fstream>
- #include <array>
- #include <filesystem>
- using namespace std;
- namespace fs = std::experimental::filesystem;
- void ru_lang();
- void dir();
- void parser(string&, vector<string>&);
- void wordsToVector(const string&, vector<string>&);
- void main_cycle();
- void mkdir_command(vector<string>&);
- void comm_command(vector<string>&);
- void comm_cycle(const vector<string>&, const bool&, const bool&, const bool&, string& filename, int& writing);
- void diff_command(vector<string>&);
- void diff_out(const vector<string>&, const vector<string>&);
- void sort_command(vector<string>&);
- void sorting_out(vector<string>&, int& writing, string& filename);
- void uniq_command(vector<string>&);
- void wc_command(vector<string>&);
- void wcCouter(string&, const bool&, const bool&, const bool&, int&, string& filename, const bool& file, const string& name);
- void cd_command(vector<string>&);
- string fileToString(const string&);
- void fileToVector(const string&, vector<string>&);
- int writingToFileCheck(vector<string>&, string&);
- void helpRealize(array<string,7>&);
- int main()
- {
- ru_lang();
- SetCurrentDirectory("D:\\");
- main_cycle();
- cout << "Работа терминала завершена" << endl;
- system("PAUSE");
- return 0;
- }
- void main_cycle()
- {
- string input;
- array<string, 8> commands = { "mkdir", "comm", "diff", "sort", "uniq", "wc", "cd", "e" };
- array<string, 7> helping;
- helpRealize(helping);
- vector<string> v_input;
- int key = 10;
- dir();
- while (getline(cin, input) && input != "quit")
- {
- bool help = false;
- bool write = false;
- bool rewrite = false;
- parser(input, v_input);
- for (unsigned int i = 0; i < commands.size(); i++)
- {
- if (v_input[0] == commands[i])
- {
- key = i;
- }
- }
- if (find(v_input.begin(), v_input.end(), ">>") != v_input.end())
- {
- write = true;
- }
- else if (find(v_input.begin(), v_input.end(), ">") != v_input.end())
- {
- rewrite = true;
- }
- if (find(v_input.begin(), v_input.end(), "--help") != v_input.end())
- {
- help = true;
- if (key < 7)
- {
- cout << helping[key];
- dir();
- }
- }
- if (!help)
- {
- switch (key)
- {
- case 0: // mkdir // В линуксе разделителем папок является '/'
- mkdir_command(v_input);
- break;
- case 1: // comm
- {
- comm_command(v_input);
- break;
- }
- case 2: // diff
- {
- diff_command(v_input);
- break;
- }
- case 3: // sort
- {
- sort_command(v_input);
- break;
- }
- case 4: // uniq
- {
- uniq_command(v_input);
- break;
- }
- case 5: // wc
- wc_command(v_input);
- break;
- case 6: // cd
- cd_command(v_input);
- break;
- case 7: // пустой ввод
- dir();
- break;
- default:
- cout << v_input[0] << ": команда не найдена" << endl;
- dir();
- break;
- }
- }
- v_input.clear();
- key = 10;
- }
- }
- void parser(string& input,vector<string>& v_input)
- {
- if (input.empty())
- {
- input.push_back('e');
- }
- wordsToVector(input, v_input);
- }
- void wordsToVector(const string& str, vector<string>& vec)
- {
- istringstream is(str); //превращаем строку в поток
- copy(istream_iterator<string>(is), istream_iterator<string>(), back_inserter(vec)); //читаем по словам и добавляем в вектор
- }
- void mkdir_command(vector<string>& v_input)
- {
- v_input.erase(v_input.begin());
- for (unsigned int i = 0; i < v_input.size(); i++)
- {
- if (!v_input[i].find('-'))
- {
- v_input.erase(v_input.begin() + i);
- i--;
- }
- }
- if (v_input.empty()) // при вводе только команды
- {
- cout << "mkdir: пропущен операнд" << endl;
- cout << "По команде «mkdir --help» можно получить дополнительную информацию." << endl;
- }
- for (unsigned int i = 0; i < v_input.size(); i++)
- {
- string clearinput = v_input[0];
- v_input[i].erase(remove(v_input[i].begin(), v_input[i].end(), '\\'), v_input[i].end());
- const char* folder = v_input[i].c_str();
- bool flag = true;
- if(fs::exists(folder))
- {
- cout << "mkdir: невозможно создать каталог «" << clearinput << "»: Файл существует" << endl;
- flag = false;
- }
- if (fs::create_directories(folder))
- {
- flag = false;
- }
- if (flag)
- {
- cout << "mkdir: невозможно создать каталог «" << clearinput << "»: Нет такого файла или каталога" << endl;
- }
- }
- dir();
- }
- void comm_command(vector<string>& v_input)
- {
- string filename;
- int writing = writingToFileCheck(v_input, filename);
- v_input.erase(v_input.begin());
- bool column1 = true;
- bool column2 = true;
- bool column3 = true;
- if (v_input.size() < 2)
- {
- cout << "comm: пропущен операнд" << endl
- << "По команде «comm --help» можно получить дополнительную информацию.";
- }
- else if (v_input.size() > 2)
- {
- if (find(v_input.begin(), v_input.end(), "-1") != v_input.end())
- {
- column1 = false;
- }
- if (find(v_input.begin(), v_input.end(), "-2") != v_input.end())
- {
- column2 = false;
- }
- if (find(v_input.begin(), v_input.end(), "-3") != v_input.end())
- {
- column3 = false;
- }
- if (find(v_input.begin(), v_input.end(), "-12") != v_input.end())
- {
- column1 = false;
- column2 = false;
- }
- if (find(v_input.begin(), v_input.end(), "-13") != v_input.end())
- {
- column1 = false;
- column3 = false;
- }
- if (find(v_input.begin(), v_input.end(), "-23") != v_input.end())
- {
- column2 = false;
- column3 = false;
- }
- for (unsigned int i = 0; i < v_input.size(); i++)
- {
- if (!v_input[i].find('-'))
- {
- v_input.erase(v_input.begin() + i);
- i--;
- }
- }
- comm_cycle(v_input, column1, column2, column3, filename, writing);
- }
- else if (v_input.size() == 2)
- {
- comm_cycle(v_input, column1, column2, column3, filename, writing);
- }
- }
- void comm_cycle(const vector<string>& v_input, const bool& column1, const bool& column2, const bool& column3, string& filename, int& writing)
- {
- vector<string> file1, file2, out1, out2, out3;
- string str;
- string path = v_input[0];
- ifstream file;
- file.open(path);
- if (file.is_open())
- {
- fileToVector(path, file1);
- file.close();
- }
- else
- {
- cout << "comm: " << v_input[0] << ": Нет такого файла или каталога" << endl;
- }
- path = v_input[1];
- file.open(path);
- if (file.is_open())
- {
- fileToVector(path, file2);
- file.close();
- }
- else
- {
- cout << "comm: " << v_input[1] << ": Нет такого файла или каталога" << endl;
- }
- int maxSize = file2.size();
- if (file1.size() <= file2.size())
- {
- file1.resize(maxSize);
- }
- else if (file1.size() > file2.size())
- {
- maxSize = file1.size();
- file2.resize(maxSize);
- };
- for (int i = 0; i < maxSize; i++)
- {
- if (file1[i] == file2[i])
- {
- out2.push_back(file1[i]);
- }
- if (file1[i] != file2[i])
- {
- out1.push_back(file1[i]);
- out3.push_back(file2[i]);
- }
- }
- out1.resize(maxSize);
- out2.resize(maxSize);
- out3.resize(maxSize);
- if (writing == 0)
- {
- for (int i = 0; i < maxSize; i++)
- {
- if (column1)
- {
- cout << out1[i] << '\t';
- }
- if (column2)
- {
- cout << out2[i] << '\t';
- }
- if (column3)
- {
- cout << out3[i];
- }
- cout << endl;
- }
- }
- else if (writing == 1)
- {
- ofstream fout;
- fout.open(filename, ios::trunc);
- for (int i = 0; i < maxSize; i++)
- {
- if (column1)
- {
- fout << out1[i] << '\t';
- }
- if (column2)
- {
- fout << out2[i] << '\t';
- }
- if (column3)
- {
- fout << out3[i];
- }
- fout << endl;
- }
- }
- else if (writing == 2)
- {
- ofstream fout;
- fout.open(filename, ios::app);
- for (int i = 0; i < maxSize; i++)
- {
- if (column1)
- {
- fout << out1[i] << '\t';
- }
- if (column2)
- {
- fout << out2[i] << '\t';
- }
- if (column3)
- {
- fout << out3[i];
- }
- fout << endl;
- }
- }
- cout << endl;
- dir();
- }
- void diff_command(vector<string>& v_input)
- {
- v_input.erase(v_input.begin());
- vector<string> file1, file2, out1, out2;
- string str;
- string path = v_input[0];
- ifstream file;
- file.open(path);
- if (file.is_open())
- {
- fileToVector(path, file1);
- file.close();
- }
- else
- {
- cout << "diff: " << v_input[0] << ": Нет такого файла или каталога" << endl;
- }
- path = v_input[1];
- file.open(path);
- if (file.is_open())
- {
- fileToVector(path, file2);
- file.close();
- }
- else
- {
- cout << "diff: " << v_input[1] << ": Нет такого файла или каталога" << endl;
- }
- unsigned int maxSize = file1.size();
- if (maxSize > file2.size())
- {
- file2.resize(maxSize);
- }
- else if (maxSize < file2.size())
- {
- maxSize = file2.size();
- file1.resize(maxSize);
- }
- for (unsigned int i = 0; i < maxSize; i++)
- {
- if (file1[i] != file2[i])
- {
- out2.push_back(file2[i]);
- out1.push_back(file1[i]);
- }
- }
- diff_out(out1, out2);
- dir();
- }
- void diff_out(const vector<string>& out1, const vector<string>& out2)
- {
- for (auto element : out1)
- {
- cout << "< " << element << endl;
- }
- cout << "---" << endl;
- for (auto element : out2)
- {
- cout << "> " << element << endl;
- }
- }
- void cd_command(vector<string>& v_input)
- {
- v_input.erase(v_input.begin());
- if (v_input.size() < 1)
- {
- v_input.push_back("0");
- SetCurrentDirectory("D:\\");
- }
- if (!(v_input[0] == "0"))
- {
- const char* p = v_input[0].c_str();
- bool flag = true;
- if (v_input.size() > 1)
- {
- cout << "cd: слишком много аргументов" << endl;
- flag = false;
- }
- if (flag)
- {
- if (!SetCurrentDirectory(p))
- {
- cout << "cd: " << p << ": Нет такого файла или каталога" << endl;
- }
- }
- }
- dir();
- }
- void sort_command(vector<string>& v_input)
- {
- string filename;
- int writing = writingToFileCheck(v_input, filename);
- v_input.erase(v_input.begin());
- vector<string> lines;
- string str;
- if (v_input.size() == 0)
- {
- while (getline(cin, str, '\n'))
- {
- lines.push_back(str);
- }
- cin.clear();
- sorting_out(lines, writing, filename);
- }
- while (v_input.size() != 0)
- {
- string path = v_input[0];
- v_input.erase(v_input.begin());
- ifstream file(path);
- if (file.is_open())
- {
- fileToVector(path, lines);
- sorting_out(lines, writing, filename);
- file.close();
- }
- else
- {
- cout << "sort: не удалось прочитать: " << v_input[0] << ": Нет такого файла или каталога";
- }
- }
- cout << endl;
- dir();
- }
- void sorting_out(vector<string>& lines, int& writing, string& filename)
- {
- sort(lines.begin(), lines.end());
- if (writing == 0)
- {
- copy(lines.begin(), lines.end(), ostream_iterator<string>(cout, "\n"));
- }
- else if (writing == 1)
- {
- ofstream fout;
- fout.open(filename, ios::trunc);
- copy(lines.begin(), lines.end(), ostream_iterator<string>(fout, "\n"));
- }
- else if (writing == 2)
- {
- ofstream fout;
- fout.open(filename, ios::app);
- copy(lines.begin(), lines.end(), ostream_iterator<string>(fout, "\n"));
- }
- }
- void uniq_command(vector<string>& v_input)
- {
- string filename;
- int writing = writingToFileCheck(v_input, filename);
- v_input.erase(v_input.begin());
- string str;
- vector<string> lines;
- if (v_input.size() == 0)
- {
- string strf;
- while (getline(cin, str, '\n'))
- {
- if (strf != str)
- {
- cout << str << endl;
- }
- strf = str;
- }
- cin.clear();
- }
- else if (v_input.size() == 1)
- {
- string path = v_input[0];
- ifstream file(path);
- if (file.is_open())
- {
- fileToVector(path, lines);
- auto x = unique(lines.begin(), lines.end());
- lines.erase(x, lines.end());
- if (writing == 0)
- {
- copy(lines.begin(), lines.end(), ostream_iterator<string>(cout, "\n"));
- }
- else if (writing == 1)
- {
- ofstream fout;
- fout.open(filename, ios::trunc);
- copy(lines.begin(), lines.end(), ostream_iterator<string>(fout, "\n"));
- }
- else if (writing == 2)
- {
- ofstream fout;
- fout.open(filename, ios::app);
- copy(lines.begin(), lines.end(), ostream_iterator<string>(fout, "\n"));
- }
- }
- else
- {
- cout << "uniq: " << v_input[0] << ": Нет такого файла или каталога";
- }
- }
- else if (v_input.size() > 1)
- {
- cout << "uniq: лишний операнд " << endl
- << "По команде «uniq --help» можно получить дополнительную информацию.";
- }
- cout << endl;
- dir();
- }
- void wc_command(vector<string>& v_input)
- {
- string filename;
- int writing = writingToFileCheck(v_input, filename);
- v_input.erase(v_input.begin());
- string str;
- bool Isfile = false;
- bool c = false;
- bool l = false;
- bool w = false;
- if (find(v_input.begin(), v_input.end(), "-c") != v_input.end())
- {
- c = true;
- }
- if (find(v_input.begin(), v_input.end(), "-l") != v_input.end())
- {
- l = true;
- }
- if (find(v_input.begin(), v_input.end(), "-w") != v_input.end())
- {
- w = true;
- }
- if (!c && !l && !w)
- {
- c = true;
- l = true;
- w = true;
- }
- for (unsigned int i = 0; i < v_input.size(); i++)
- {
- if (!v_input[i].find('-'))
- {
- v_input.erase(v_input.begin() + i);
- i--;
- }
- }
- vector<string>::iterator position = find(v_input.begin(), v_input.end(), "*.txt");
- if (position != v_input.end())
- {
- v_input.erase(position);
- string path;
- WIN32_FIND_DATA FindFileData;
- HANDLE hf;
- path = fs::current_path().u8string();
- path += "\\*.txt";
- hf = FindFirstFile(path.c_str() , &FindFileData);
- if (hf != INVALID_HANDLE_VALUE)
- {
- do
- {
- v_input.push_back(FindFileData.cFileName);
- }
- while (FindNextFile(hf, &FindFileData) != 0);
- FindClose(hf);
- }
- }
- if (v_input.size() == 0)
- {
- string path = "";
- getline(cin, str, '\0');
- cin.clear();
- wcCouter(str, c, l, w, writing, filename, Isfile, path);
- }
- while (v_input.size() != 0)
- {
- Isfile = true;
- string path = v_input[0];
- ifstream file(path);
- if (file.is_open())
- {
- str = fileToString(path);
- wcCouter(str, c, l, w, writing, filename, Isfile, path );
- file.close();
- }
- else
- {
- cout << "wc: " << v_input[0] << ": Нет такого файла или каталога";
- }
- v_input.erase(v_input.begin());
- }
- cout << endl;
- dir();
- }
- void wcCouter( string& str, const bool& c, const bool& l, const bool& w, int& writing, string& filename, const bool& Isfile, const string& name)
- {
- int strings = 0;
- int words = 0;
- int size = str.length();
- if (Isfile)
- {
- if (str[str.size() - 1] != '\n')
- {
- strings++;
- }
- }
- for (unsigned int i = 0; i < str.length(); i++)
- {
- if (str[i] == '\n')
- {
- strings++;
- }
- }
- istringstream is(str);
- vector<string> word;
- while (is >> str)
- {
- word.push_back(str);
- words++;
- }
- if (writing == 0)
- {
- if (c)
- {
- cout << strings << '\t';
- }
- if (l)
- {
- cout << words << '\t';
- }
- if (w)
- {
- cout << size << '\t';
- }
- cout << name << endl;
- }
- else if (writing == 1)
- {
- ofstream fout;
- fout.open(filename, ios::trunc);
- if (c)
- {
- fout << strings << '\t';
- }
- if (l)
- {
- fout << words << '\t';
- }
- if (w)
- {
- fout << size << '\t';
- }
- fout << endl;
- }
- else if (writing == 2)
- {
- ofstream fout;
- fout.open(filename, ios::app);
- if (c)
- {
- fout << strings << '\t';
- }
- if (l)
- {
- fout << words << '\t';
- }
- if (w)
- {
- fout << size << '\t';
- }
- fout << endl;
- }
- }
- void ru_lang()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- }
- void dir() // user:~/qwe$
- {
- cout << "user:~" << fs::current_path() << "# ";
- }
- string fileToString(const string& file)
- {
- ifstream f(file);
- stringstream ss;
- ss << f.rdbuf();
- return ss.str();
- }
- void fileToVector(const string& file, vector<string>& vec)
- {
- ifstream f(file);
- string str;
- while (getline(f, str, '\n'))
- {
- vec.push_back(str);
- }
- }
- int writingToFileCheck(vector<string>& v_input, string& filename)
- {
- int result;
- if (find(v_input.begin(), v_input.end(), ">>") != v_input.end())
- {
- result = 2;
- }
- else if (find(v_input.begin(), v_input.end(), ">") != v_input.end())
- {
- result = 1;
- }
- else
- {
- result = 0;
- }
- if (result == 2)
- {
- vector<string>::iterator position = find(v_input.begin(), v_input.end(), ">>");
- if (position != v_input.end())
- {
- filename = v_input[distance(v_input.begin(), position + 1)];
- v_input.erase(position, position + 2);
- }
- }
- else if (result == 1)
- {
- vector<string>::iterator position = find(v_input.begin(), v_input.end(), ">");
- if (position != v_input.end())
- {
- filename = v_input[distance(v_input.begin(), position + 1)];
- v_input.erase(position, position + 2);
- }
- }
- return result;
- }
- void helpRealize(array<string,7>& helping)
- {
- //mkdir
- helping[0] = "Использование: mkdir [КЛЮЧ]… КАТАЛОГ… \n\
- Создает КАТАЛОГ(и), если он ещё не существует.\n";
- //comm
- helping[1] = "Использование: comm [КЛЮЧ]… ФАЙЛ1 ФАЙЛ2\n\
- Сравнивает сортированные файлы ФАЙЛ1 и ФАЙЛ2 построчно.\n\
- \n\
- Если ФАЙЛ1 или ФАЙЛ2(но не оба) задан как - , читается стандартный ввод.\n\
- \n\
- При запуске без ключей выдает результат в три столбца.Первый столбец\n\
- содержит строки, уникальные для ФАЙЛА1, второй — уникальные для\n\
- ФАЙЛА2, а третий — общие для обоих файлов строки.\n\
- \n\
- - 1 не показывать столбец 1 (строки, уникальные\n\
- для ФАЙЛА1)\n\
- - 2 не показывать столбец 2 (строки, уникальные\n\
- для ФАЙЛА2)\n\
- - 3 не показывать столбец 3 (строки, встреченные\n\
- в обоих файлах)\n";
- //diff
- helping[2] = "Использование: diff [КЛЮЧ]? ФАЙЛЫ\n\
- Построчно сравнивает ФАЙЛЫ.\n";
- //sort
- helping[3] = "Использование: sort [КЛЮЧ]… [ФАЙЛ]…\n\
- или: sort[КЛЮЧ]… --files0 - from = Ф\n\
- Печатает сортированное слияние всех ФАЙЛ(ов) на стандартный вывод.\n";
- //uniq
- helping[4] = "Использование: uniq [КЛЮЧ]… [ВХОД [ВЫХОД]]\n\
- Фильтрует совпавшие строки из ВХОДА(или стандартного ввода),\n\
- записывая их в ВЫХОД(или стандартный вывод).\n";
- //wc
- helping[5] = "Использование: wc [КЛЮЧ]… [ФАЙЛ]…\n\
- или: wc[КЛЮЧ]… --files0 - from = Ф\n\
- Печатает число символов новой строки, слов и байт для каждого ФАЙЛА и\n\
- итоговую строку, если было задано несколько ФАЙЛОВ.Словом считается\n\
- последовательность символов ненулевой длины, отделённая пробельным символом.\n\
- \n\
- Если ФАЙЛ не задан или задан как - , читает стандартный ввод.\n\
- \n\
- Для выбора выводимых счётчиков используются следующие параметры\n\
- (счётчики всегда выводятся в таком порядке : символы новой строки,\n\
- слова, символы, байты, максимальная длина строки) :\n\
- -c, напечатать количество символов\n\
- -l, напечатать количество новых строк\n\
- -w, напечатать количество слов\n";
- //cd
- helping[6] = "cd: cd [-L|[-P [-e]] [-@]] [каталог]\n\
- Изменяет рабочую директорию оболочки.\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement