Advertisement
agul

20121230

Dec 29th, 2012
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.05 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. #include <cstring>
  4.  
  5. /*
  6.     Вызов программы из командной строки:
  7.  
  8.     replacer.exe [%MODE%] [-price %PRICE%] [-inputFile %INPUT_FILE%] [-outputFile %OUTPUT_FILE%]
  9.  
  10.         * в квадратных скобках обозначены необязательные параметры
  11.         * каждый параметр может быть указан перечислен произвольное количество раз, учитывается только последнее указание
  12.         * если параметр не перечислен, используется стандартное значение
  13.         * стандартные значения (их можно легко поменять в коде):
  14.             > -replaceSpaces
  15.             > -price            = 4
  16.             > -inputFile        = "input.txt"
  17.             > -outputFile       = "hfile.out"
  18.         * %MODE%        : -replaceSpaces или -replaceTabs
  19.         * -price        : "цена символа"
  20.         * -inputFile    : имя входного файла
  21.         * -outputFile   : имя выходного файла
  22.  
  23. */
  24.  
  25. using namespace std;
  26.  
  27. const int MAX_BLOCK_SIZE = 8;                       // максимальная "цена символа"
  28.  
  29. char * outputFileName = "hfile.out";                // output-файл
  30.  
  31. int blockSize = 4;                                  // здесь будет храниться размер блока пробелов, который нужно менять
  32.                                                     // на табулятор
  33.  
  34. char cache[MAX_BLOCK_SIZE];                         // здесь будут храниться последние blockSize символов из файла, назовём это кэшем
  35. FILE * in, * out;                                   // файловые переменные
  36. bool replaceSpacesMode = true;                      // показывает, в каком режиме работаем
  37.  
  38. void done() {                                       // выводим информацию о том, что всё закончили, закрываем файлы
  39.     cout << endl << "Processing done. Result is written to \"" << outputFileName << "\"." << endl;
  40.     fclose(in);
  41.     fclose(out);
  42. }
  43.  
  44. char get() {                                        // грамотное считывание символа из файла
  45.     char tmp;
  46.     if (fscanf(in, "%c", &tmp) != 1) return EOF;
  47.     return tmp;
  48. }
  49.  
  50. void put(char x) {                                  // удобная запись символа в файл
  51.     if (x) fputc(x, out);
  52. }
  53.  
  54. void loadData(int argc, char ** argv) {             // обрабатываем параметры командной строки
  55.     char * inputFileName;
  56.     for (int i = 1; i < argc; ++i)
  57.         if (strlen(argv[i]) == 14 && strstr(argv[i], "-replaceSpaces")) replaceSpacesMode = true; else
  58.         if (strlen(argv[i]) == 12 && strstr(argv[i], "-replaceTabs")) replaceSpacesMode = false; else
  59.         if (strlen(argv[i]) == 6 && strstr(argv[i], "-price")) {
  60.             if (i == argc - 1) {
  61.                 cout << "Error! Parametr \"-price\" is not specified!" << endl;
  62.                 exit(0);
  63.             }
  64.             blockSize = atoi(argv[++i]);
  65.             if (blockSize < 2 || blockSize > MAX_BLOCK_SIZE) {
  66.                 cout << "Error! Price must be an integer between 2 and " << MAX_BLOCK_SIZE << "." << endl;
  67.                 exit(0);
  68.             }
  69.         } else
  70.         if (strlen(argv[i]) == 10 && strstr(argv[i], "-inputFile")) {
  71.             if (i == argc - 1) {
  72.                 cout << "Error! Parametr \"-inputFile\" is not specified!" << endl;
  73.                 exit(0);
  74.             }
  75.             inputFileName = argv[++i];
  76.         } else
  77.         if (strlen(argv[i]) == 11 && strstr(argv[i], "-outputFile")) {
  78.             if (i == argc - 1) {
  79.                 cout << "Error! Parametr \"-outputFile\" is not specified!" << endl;
  80.                 exit(0);
  81.             }
  82.             outputFileName = argv[++i];
  83.         } else {
  84.             cout << "Error! Unknown parametr \"" << argv[i] << "\" specified!" << endl;
  85.             exit(0);
  86.         }
  87. }
  88.  
  89. void createCache() {                                // считываем первые (blockSize - 1) символов
  90.     memset(cache, 0, sizeof(cache));
  91.     for (int i = 0; i < blockSize - 1; ++i) {
  92.         cache[i] = get();
  93.         if (cache[i] == EOF) {                      // если в файле меньше blockSize символов, то сразу запишем их в output-файл
  94.                                                     // и выйдем из программы
  95.             for (int j = 0; j <= i; ++j)
  96.                 put(cache[j]);
  97.             done();
  98.             exit(0);                                // выходим из программы
  99.         }
  100.     }
  101. }
  102.  
  103. void replaceSpaces() {                              // функция, которая заменяет пробелы на табуляторы
  104.     bool first = true,                              // показывает, является ли текущий символ первым после считанного блока из
  105.                                                     // (blockSize - 1) символов
  106.          needReplace;                               // показывает, нужно ли менять последние символы на табулятор
  107.     char ch;                                        // текущий символ
  108.     int current = blockSize - 1;                    // ячейка кэша, куда нужно писать текущий символ
  109.     while ((ch = get()) != EOF) {
  110.         cache[current] = ch;
  111.         needReplace = true;
  112.         for (int i = 0; needReplace && i < blockSize; ++i)
  113.             needReplace &= (cache[i] == ' ');
  114.         current = (current + 1) % blockSize;
  115.         if (needReplace) {
  116.             put('\t');
  117.             memset(cache, 0, sizeof(cache));        // обнуляем кэш, если вывели табулятор, чтобы не выводить лишние табуляторы
  118.                                                     // в случае длинной последовательности пробелов
  119.         } else put(cache[current]);
  120.     }
  121.     for (int i = current + 1; i < blockSize; ++i)   // выводим остатки кэша
  122.         put(cache[i]);
  123.     for (int i = 0; i < current; ++i)
  124.         put(cache[i]);
  125. }
  126.  
  127. void replaceTabs() {
  128.     char ch;
  129.     while ((ch = get()) != EOF)
  130.         if (ch == '\t')
  131.             for (int i = 0; i < blockSize; ++i)
  132.                 put(' ');
  133.         else put(ch);
  134. }
  135.  
  136. int main(int argc, char ** argv) {
  137.     loadData(argc, argv);
  138.     if (!(out = fopen(outputFileName, "wt"))) {     // если открыть output-файл не получилось
  139.         cout << "Error! Unable to open file \"" << outputFileName << "\" for writing!" << endl;
  140.         return 0;
  141.     }
  142.     if (replaceSpacesMode) {
  143.         createCache();
  144.         replaceSpaces();
  145.     } else replaceTabs();
  146.     done();
  147.     return 0;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement