Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <cstring>
- /*
- Вызов программы из командной строки:
- replacer.exe [%MODE%] [-price %PRICE%] [-inputFile %INPUT_FILE%] [-outputFile %OUTPUT_FILE%]
- * в квадратных скобках обозначены необязательные параметры
- * каждый параметр может быть указан перечислен произвольное количество раз, учитывается только последнее указание
- * если параметр не перечислен, используется стандартное значение
- * стандартные значения (их можно легко поменять в коде):
- > -replaceSpaces
- > -price = 4
- > -inputFile = "input.txt"
- > -outputFile = "hfile.out"
- * %MODE% : -replaceSpaces или -replaceTabs
- * -price : "цена символа"
- * -inputFile : имя входного файла
- * -outputFile : имя выходного файла
- */
- using namespace std;
- const int MAX_BLOCK_SIZE = 8; // максимальная "цена символа"
- char * outputFileName = "hfile.out"; // output-файл
- int blockSize = 4; // здесь будет храниться размер блока пробелов, который нужно менять
- // на табулятор
- char cache[MAX_BLOCK_SIZE]; // здесь будут храниться последние blockSize символов из файла, назовём это кэшем
- FILE * in, * out; // файловые переменные
- bool replaceSpacesMode = true; // показывает, в каком режиме работаем
- void done() { // выводим информацию о том, что всё закончили, закрываем файлы
- cout << endl << "Processing done. Result is written to \"" << outputFileName << "\"." << endl;
- fclose(in);
- fclose(out);
- }
- char get() { // грамотное считывание символа из файла
- char tmp;
- if (fscanf(in, "%c", &tmp) != 1) return EOF;
- return tmp;
- }
- void put(char x) { // удобная запись символа в файл
- if (x) fputc(x, out);
- }
- void loadData(int argc, char ** argv) { // обрабатываем параметры командной строки
- char * inputFileName;
- for (int i = 1; i < argc; ++i)
- if (strlen(argv[i]) == 14 && strstr(argv[i], "-replaceSpaces")) replaceSpacesMode = true; else
- if (strlen(argv[i]) == 12 && strstr(argv[i], "-replaceTabs")) replaceSpacesMode = false; else
- if (strlen(argv[i]) == 6 && strstr(argv[i], "-price")) {
- if (i == argc - 1) {
- cout << "Error! Parametr \"-price\" is not specified!" << endl;
- exit(0);
- }
- blockSize = atoi(argv[++i]);
- if (blockSize < 2 || blockSize > MAX_BLOCK_SIZE) {
- cout << "Error! Price must be an integer between 2 and " << MAX_BLOCK_SIZE << "." << endl;
- exit(0);
- }
- } else
- if (strlen(argv[i]) == 10 && strstr(argv[i], "-inputFile")) {
- if (i == argc - 1) {
- cout << "Error! Parametr \"-inputFile\" is not specified!" << endl;
- exit(0);
- }
- inputFileName = argv[++i];
- } else
- if (strlen(argv[i]) == 11 && strstr(argv[i], "-outputFile")) {
- if (i == argc - 1) {
- cout << "Error! Parametr \"-outputFile\" is not specified!" << endl;
- exit(0);
- }
- outputFileName = argv[++i];
- } else {
- cout << "Error! Unknown parametr \"" << argv[i] << "\" specified!" << endl;
- exit(0);
- }
- }
- void createCache() { // считываем первые (blockSize - 1) символов
- memset(cache, 0, sizeof(cache));
- for (int i = 0; i < blockSize - 1; ++i) {
- cache[i] = get();
- if (cache[i] == EOF) { // если в файле меньше blockSize символов, то сразу запишем их в output-файл
- // и выйдем из программы
- for (int j = 0; j <= i; ++j)
- put(cache[j]);
- done();
- exit(0); // выходим из программы
- }
- }
- }
- void replaceSpaces() { // функция, которая заменяет пробелы на табуляторы
- bool first = true, // показывает, является ли текущий символ первым после считанного блока из
- // (blockSize - 1) символов
- needReplace; // показывает, нужно ли менять последние символы на табулятор
- char ch; // текущий символ
- int current = blockSize - 1; // ячейка кэша, куда нужно писать текущий символ
- while ((ch = get()) != EOF) {
- cache[current] = ch;
- needReplace = true;
- for (int i = 0; needReplace && i < blockSize; ++i)
- needReplace &= (cache[i] == ' ');
- current = (current + 1) % blockSize;
- if (needReplace) {
- put('\t');
- memset(cache, 0, sizeof(cache)); // обнуляем кэш, если вывели табулятор, чтобы не выводить лишние табуляторы
- // в случае длинной последовательности пробелов
- } else put(cache[current]);
- }
- for (int i = current + 1; i < blockSize; ++i) // выводим остатки кэша
- put(cache[i]);
- for (int i = 0; i < current; ++i)
- put(cache[i]);
- }
- void replaceTabs() {
- char ch;
- while ((ch = get()) != EOF)
- if (ch == '\t')
- for (int i = 0; i < blockSize; ++i)
- put(' ');
- else put(ch);
- }
- int main(int argc, char ** argv) {
- loadData(argc, argv);
- if (!(out = fopen(outputFileName, "wt"))) { // если открыть output-файл не получилось
- cout << "Error! Unable to open file \"" << outputFileName << "\" for writing!" << endl;
- return 0;
- }
- if (replaceSpacesMode) {
- createCache();
- replaceSpaces();
- } else replaceTabs();
- done();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement