На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Может кто объяснить в чем ошибка?, ошибок не выдает, но не компилится Borland++ 3.1
    ExpandedWrap disabled
      Unit1.h
      //------------------------------------------------------------------------------
      #ifndef Unit1H
      #define Unit1H
      //------------------------------------------------------------------------------
      #include <Classes.hpp>
      #include <Controls.hpp>
      #include <StdCtrls.hpp>
      #include <Forms.hpp>
      #include <Buttons.hpp>
      #include <ExtCtrls.hpp>
      #include <Dialogs.hpp>
      #include <ExtDlgs.hpp>
      #include <ComCtrls.hpp>
      #include <Menus.hpp>
      //------------------------------------------------------------------------------
      class TForm1 : public TForm
      {
      __published:    // IDE-managed Components
              TButton *Button1;           //Кнопка "Кодировать"
              TLabeledEdit *LabeledEdit1; //Поле ввода пути к каталогу
              TSpeedButton *SpeedButton1; //Кнопка выбора пути к каталогу
              TLabeledEdit *LabeledEdit2; //Поле ввода имени файла архива
              TSpeedButton *SpeedButton2; //Кнопка ввода имени файла архива
              TButton *Button2;           //Кнопка "Декодировать"
              TLabel *Label1;             //Информационная надпись
              TSaveDialog *SaveDialog1;   //Компонент диалога сохранения файлов
              TProgressBar *ProgressBar1; //Индикатор состояния процесса
              TMainMenu *MainMenu1;       //Компонент главного меню формы
              TMenuItem *N1;              //Кнопка главного меню "О программе"
              void __fastcall Button1Click(TObject *Sender);
              void __fastcall Button2Click(TObject *Sender);
              void __fastcall SpeedButton1Click(TObject *Sender);
              void __fastcall SpeedButton2Click(TObject *Sender);
              void __fastcall N1Click(TObject *Sender);
      private:    // User declarations
      public:     // User declarations
              __fastcall TForm1(TComponent* Owner);
      };
      //------------------------------------------------------------------------------
      extern PACKAGE TForm1 *Form1;
      //------------------------------------------------------------------------------
      #endif

    ExpandedWrap disabled
      Unit1.cpp
      //------------------------------------------------------------------------------
      #include <vcl.h>
      #include <stdio.h>
      #include <FileCtrl.hpp>
      #include "Unit1.h"
      #include "Unit2.h"
      #pragma hdrstop
      //------------------------------------------------------------------------------
      #pragma package(smart_init)
      #pragma resource "*.dfm"
       
      // Количество битов в регистре. 16 Вполне достаточно для 256 символов
      #define BITS_IN_REGISTER 16
       
      // Максимально возможное значение в регистре
      #define TOP_VALUE (((long) 1 << BITS_IN_REGISTER) - 1)
      // Диапазоны
      #define FIRST_QTR (TOP_VALUE / 4 + 1)   //Первая четверть
      #define HALF      (2 * FIRST_QTR)       //Вторая четверть
      #define THIRD_QTR (3 * FIRST_QTR)       //Третья четверть
      #define NO_OF_CHARS 256  // Количество символов алфавита
      #define EOF_SYMBOL    (NO_OF_CHARS + 1) // Специальный символ "Конец Файла"
      #define NO_OF_SYMBOLS (NO_OF_CHARS + 1) // Всего символов в модели
      // Порог частоты для масштабирования 16383 в нашем случае
      #define MAX_FREQUENCY (((long) 1 << BITS_IN_REGISTER-2) - 1)
       
      // Таблицы пеpекодиpовки исходных и рабочих символов
      unsigned char  index_to_char [NO_OF_SYMBOLS]; //Из рабочего в исходный
      short int      char_to_index [NO_OF_CHARS];  //Из исходного в рабочий
       
      // Таблицы частот
      short int   cum_freq [NO_OF_SYMBOLS + 1]; //Суммарные частоты (с учетом менее
                                            //встречаемых символов рабочего алфавита)
      short int   freq [NO_OF_SYMBOLS + 1]; // частоты (без учета менее
                                            //встречаемых символов рабочего алфавита)
      // Регистры границ и кода
      unsigned short int  low, high;    // Нижняя и верхняя границы текущего интервала
      unsigned short int  value; //Текущее значение части входного числа(используется
                                 //только при деархивации)
       
      // Поддержка побитлвых операций с файлами
      long  bits_to_follow; // Количество подряд идущих "1" либо "0", хранящихся в
                            //памяти для предотвращения отрицательного переполнения
      short int   buffer;   // Переменная используемая для накопления отдельных битов
                            //перед записью в файл при кодировании,
                            //либо хранения после чтения из файла при декодировании
      short int   bits_to_go; //Количество свободных в буфере битов при кодировании,
          //либо занятых при декодированни;
       
      // Обрабатываемые файлы
      FILE *in,*out;  // соответственно входной и выходной файлы
       
      struct spisok   //Структура записи динамического списка файлов текущей папки
                      //при кодировании, либо файлов в архиве при декодировании
      {
        char *filename; //Указатель на строку, содержащую относительный путь к файлу
                        //и имя самого файла
        struct spisok *nextPtr;  // указатель на следующий элемент списка
      };
       
      typedef struct spisok Spisok; // Всю структуру определяем как "Spisok"
      typedef Spisok * SpisokPtr;  //а указатель на нее как "SpisokPtr"
      SpisokPtr headPtr=NULL;  //Указатель на первый элемент списка
      SpisokPtr tekPtr=NULL;   //Указатель на текущий элемент списка
      AnsiString Path0; // Путь текущего каталога
      AnsiString Path1; // Относительные пути к файлам (относительно текущего каталога)
                        // Path0+Path1 образует полный путь к файлу
      unsigned short int nf; //количество файлов в архиве
      TForm1 *Form1; //Главная форма программы архиватора
       
      //------------------------------------------------------------------------------
      //Эту процедуру сделала среда разработки, я пока не знаю, для чего она
      __fastcall TForm1::TForm1(TComponent* Owner)
              : TForm(Owner)
      {
      }
       
      //------------------------------------------------------------------------------
      // Инициализация адаптивной модели
       
      void start_model (void)
      {
        int i;
      // Установка   таблиц пеpекодиpовки  между исходными и рабочими символами
        for ( i = 0; i < NO_OF_CHARS; i++)
        {
          char_to_index [i] = i + 1;
          index_to_char [i + 1] = i;
        }
        for ( i = 0; i <= NO_OF_SYMBOLS; i++)
        {
          freq [i] = 1;  //Установка значений счетчиков частот в 1 для  всех символов
          cum_freq [i] = NO_OF_SYMBOLS - i; //Установка значений суммарных частот
        }
        freq [0] = 0;  //freq[0] должен быть меньше freq[1], чтобы процедура обновления
                       //таблиц перекодировки работала корректно
      }
       
      //------------------------------------------------------------------------------
      // Обновление модели очередным символом, входной параметр-индекс нового символа
       
      void update_model ( int symbol)
      {
        short int i;     // Новый индекс этого символа
        short int ch_i;  // Символ рабочего алфавита, соответствующий i
        short int ch_symbol; // Символ рабочего алфавита, соответствующий symbol
        // масштабирование частот при переполнении
        // проверка на переполнение счетчика частоты
        if (cum_freq [0] == MAX_FREQUENCY)// Если счетчики частот  достигли максимума
        {
          short int cum=0; //Переменная, в которой накапливается суммарная частота
          for ( i = NO_OF_SYMBOLS; i >= 0; i--)
          {
            freq [i] = (freq [i] + 1) / 2; //Тогда  делим их  всех  пополам,
                                           //не приводя к нулю
            cum_freq [i] = cum;  //Обновляем суммарные частоты
            cum += freq [i];
          }
        }
        //Находим самый малый символ в таблице с такой же частотой
        for ( i = symbol; freq [i] == freq [i - 1]; i--);
        if (i < symbol) //Если он меньше нового символа, то
        {  //меняем их местами, в обоих таблицах
          ch_i                      = index_to_char [i];
          ch_symbol                 = index_to_char [symbol];
          index_to_char [i]         = ch_symbol;
          index_to_char [symbol]    = ch_i;
          char_to_index [ch_i]      = symbol;
          char_to_index [ch_symbol] = i;
        }
        // обновление значений в таблицах частот
        freq [i] += 1; //увеличиваем частоту нового символа
        for(;i>0;++cum_freq [--i]); //увеличиваем суммарные частоты более частых
                                    //символов;
      }
       
      //------------------------------------------------------------------------------
      // Инициализация побитового ввода
      void start_inputing_bits (void)
      {
        bits_to_go = 0; //Количество занятых в буфере битов перед декодированием 0
      }
       
      //------------------------------------------------------------------------------
      // Ввод очередного бита сжатой информации, возвращает очередной бит
       
      int input_bit (void)
      {
        int t;  //Переменная, в которой будет хранится введенный бит
        if (bits_to_go == 0)//Если буфер пустой
        {
          buffer = getc(in); //считываем очередной символ из файла
          bits_to_go = 8;  //количество занятых битов устанавливаем 8
        }
        t = buffer & 1; //помещаем в t значение младшего бита буфера
        buffer >>= 1;   //сдвигаем буфер на 1 бит вправо
        bits_to_go-- ;  //уменьшаем количество занятых битов
        return t;       //возвращаем значение t
      }
       
      //------------------------------------------------------------------------------
      // Инициализация побитового вывода
       
      void start_outputing_bits (void)
      {
        bits_to_go = 8;  //устанавливаем количество свободных битов буфера 8
        buffer = 0;      //устанавливаем значение буфера 0
      }
       
      //------------------------------------------------------------------------------
      // Вывод очередного бита сжатой информации, входной параметр-выходной бит
       
      void output_bit ( int bit)
      {
        buffer >>= 1;   //сдвигаем буфер на 1 вправо, чтобы освободить место
                        //старшего бита очередному биту
        if (bit)        //если очередной бит равен 1, то
          buffer |= 0x80;  //в старший бит буфера устанавливаем 1
        bits_to_go-- ;   //уменьшаем количество свободных битов буфера
        if (bits_to_go == 0) //Если свободных битов не осталось, то
        {
          putc ( buffer, out); //Записываем буфер в выходной файл
          bits_to_go = 8;  //устанавливаем количество свободных битов буфера 8
        }
      }
       
      //------------------------------------------------------------------------------
      // Очистка буфера побитового вывода
       
      void done_outputing_bits (void)
      {   //записываем в выходной файл значение буфера, сдвинутое на количество
        putc ( buffer >> bits_to_go, out); //свободных битов
      }
       
      //------------------------------------------------------------------------------
      // Вывод указанного бита и отложенных ранее, входной параметр-выходной бит
       
      void output_bit_plus_follow (short int bit)
      {
        output_bit (bit); //заносим выходной бит в буфер
        //и вслед за ним количество отложенных ранее противоположных битов
        for( ; bits_to_follow > 0; bits_to_follow-- ) output_bit (!bit);
      }
       
      //------------------------------------------------------------------------------
      // Инициализация регистров границ и кода перед началом сжатия
       
      void start_encoding (void)
      {
        low            = 0;        //в нижней границе устанавливаем все нули
        high           = TOP_VALUE; //в верхней - все единицы
        bits_to_follow = 0;  //количество отложенных битов устанавливаем 0
      }
       
      //------------------------------------------------------------------------------
      // Завершение кодирования потока
       
      void done_encoding (void)
      {
        bits_to_follow++;               //Здесь происходит вывод двух битов
        if (low < FIRST_QTR)            //определяющих четверть, лежащую в
          output_bit_plus_follow (0);   //текущем интервале  
        else
          output_bit_plus_follow (1);
      }
       
      //------------------------------------------------------------------------------
      // Инициализация регистров перед декодированием.
      // Загрузка начала сжатого сообщения
       
       
      void start_decoding (void)
      {
        int i;
        value = 0;               //Все биты части входного сигнала заполняем
        for ( i = 1; i <= BITS_IN_REGISTER; i++) //начальными битами
          value = 2 * value + input_bit ();      //входного файла
        low = 0;           //в нижней границе устанавливаем все нули
        high = TOP_VALUE;  //в верхней - все единицы
      }
       
      //------------------------------------------------------------------------------
      // Кодирование очередного символа, входной параметр - кодируемый символ
       
      void encode_symbol ( int symbol)
      {
        long range;  //Шиpина текущего кодового интервала
        range = (long) (high - low) + 1; //Сужение интервала кодов
                                         //до выделенного для symbol
        // пересчет значений границ, соответственно верхней и нижней                                
        high = low + (range * cum_freq [symbol - 1]) / cum_freq [0] - 1;
        low = low + (range * cum_freq [symbol]) / cum_freq [0];
        // выдвигание очередных битов
        for (;;) //Цикл с заранее неизвестным числом повторений
        {
          if (high < HALF) //Если в обоих границах старшие биты нули,
            output_bit_plus_follow (0); //то выводим 0
          else if (low >= HALF) //Если в обоих границах старшие биты  единицы,
                 output_bit_plus_follow (1); //то выводим 1
            else if (low >= FIRST_QTR && high < THIRD_QTR)
            {      //Если текущий интервал содержит середину исходного,
              bits_to_follow += 1;//то вывод еще одного обратного бита позже,
              low -= FIRST_QTR;   //а сейчас убрать общую часть
              high -= FIRST_QTR;
            }
            else break;  //Иначе выйти из цикла
          // Расширить текущий рабочий кодовый интервал
          // сдвигом влево с "втягиванием" очередного бита
          low <<=1;   //В младший байт нижней границы втягивается 0
          high<<=1;
          high++;     //В младший байт верхней границы втягивается 1
        }
      }
       
      //------------------------------------------------------------------------------
      // Декодирование очередного символа, возвращает символ рабочего алфавита
       
      int decode_symbol (void)
      {
        long range; //Ширина текущего кодового интервала
        int cum;    //Суммарная частота для текущего символа
        int symbol; //Значение символа рабочего алфавита
        range = (long) (high - low) + 1;//определение текущего масштаба частот
        // масштабирование значения в регистре кода
        cum = (int)((((long) (value - low) + 1) * cum_freq [0] - 1) / range);
        // поиск соответствующего символа в таблице частот
        for (symbol = 1; cum_freq [symbol] > cum; symbol++);
        // пересчет границ
        high = low + (range * cum_freq [symbol - 1]) / cum_freq [0] - 1;
        low = low + (range * cum_freq [symbol]) / cum_freq [0];
        // удаление очередного символа из входного потока
        for (;;) //Цикл с заранее неизвестным числом повторений
        {
          if (high >= HALF)  //Если старший бит верхней границы 1,то
           if (low < HALF)   //Если младший бит нижней границы 0,то
            if (low < FIRST_QTR || high >= THIRD_QTR)//Если текущий интервал не
              break; //содеpжит сеpедину исходного, то выходим из цикла
            else  //Иначе
            {     //Убираем общую часть
              value -= FIRST_QTR;
              low -= FIRST_QTR;
              high -= FIRST_QTR;
            }
          // сдвиг влево с втягиванием очередного бита
          low <<=1; //В младший байт нижней границы втягивается 0
          high<<=1;
          high++;   //В младший байт верхней границы втягивается 1
          value<<=1;
          value+=input_bit(); //В текущее значение части входного числа
        }                     //втягивается следующий бит
        return symbol; //Возвращаем значение символа рабочего алфавита
      }
       
      //------------------------------------------------------------------------------
      //Добавление файла в динамический список, входной параметр- указатель на
      //имя файла
      void addfile(char *fn)
      {
        char *st; //Указатель на строку, содержащую имя файла и относительный
                  //путь к нему
        SpisokPtr newPtr; //Указатель на новый элемент списка
        st=(char*)malloc(strlen(fn)+strlen(Path1.c_str())+1); //Выделяем память
        //для хранения строки, содержащей имя файла и относительный путь к нему
        strcpy(st,Path1.c_str());//Копируем относительный путь
        strcat(st,fn);  //Добавляем имя файла
        newPtr=(Spisok*)malloc(sizeof(Spisok));//Выделяем память под новый
                                               //элемент списка
        newPtr->filename=st; //Ставим в соответствие указателю на строку в
                             //элементе списка, указатель на созданную строку
        if (headPtr==NULL)  //Если список до этого не содержал ни одного
                            //элемента,то
            headPtr=newPtr; //делаем его первым элементом списка
          else  tekPtr->nextPtr=newPtr; //иначе вставляем его после текущего
        tekPtr=newPtr; //делаем новый элемент списка текущим
        tekPtr->nextPtr=NULL; //Помещаем в указатель на следующий элемент NULL
      }
       
      //------------------------------------------------------------------------------
      //Обход файлов текущего каталога и всех его подкаталогов(всего дерева)
      void obhod(void)  
      {
       TSearchRec sr; //Структура хранящая информацию о найденных файлах
       if (FindFirst("*", faAnyFile, sr) == 0) //Ищем первый файл
       {
         do
         {   //Если текукщий файл - не является каталогом, то
           if ((sr.Attr & faDirectory) != faDirectory  )
           {
             char filename[MAX_PATH]; //Массив символов, содержащий имя файла
             strcpy(filename,sr.Name.c_str());//Копируем в него имя файла
             addfile(filename); //Добавляем его в динамический список файлов
             nf++;  //Увеличиваем количество файлов в архиве
           }
         }
         while (FindNext(sr) == 0); //Пока не нашли все файлы в каталоге
         // обработка подкаталогов текущего каталога
         if (FindFirst("*", faDirectory, sr) == 0 ) //Если, предположительно,
                                                    //нашли каталог
         do
         {
           if ((sr.Attr & faDirectory) == faDirectory) //Если он действительно
                                                       //является каталогом
           if (sr.Name[1] != '.' ) //Если это не указатель на родительский
           {                       //каталог
             AnsiString olds=Path1;//Сохраняем относительный путь в строке olds
             Path1+=sr.Name+"\\";  //Добавляем к имени относительного пути имя
                                   //найденного каталога и наклонную черту
             ChDir(sr.Name);// входим в каталог
             obhod(); // выполняем поиск в подкаталоге
             Path1=olds;  // Возвращаем относительный путь
             ChDir(".."); // выходим из каталога
           }
         }
         while (FindNext(sr)==0); //пока не нашли все подкаталоги в текущем каталоге
         FindClose(sr); //закрываем поиск
       }
      }
       
      //------------------------------------------------------------------------------
      //Функщия, которая выполняется перед каждым сеансом кодирования и декодирования
      void start(void)
      {
        char buf[MAX_PATH]; //Массив символов, в котором производится преобразование
                            //пути каталога архивирования
        char *p;  //указатель для поиска в нем символа '\'
        nf=0;    //Устанавливаем количество файлов в 0
        tekPtr=headPtr; //Первый элемент списка делаем текущим
        strcpy(buf,Form1->LabeledEdit1->Text.c_str());//Копируем в buf строку из
                                                      //LabeledEdit1
        p=strchr(buf,0); //ставим указатель p на символ конца строки buf
        if(*(p-1)!='\\') //если последний символ строки buf не '\', то
              strcpy(p,"\\");   //добавляем к строке '\'
        Path0=AnsiString(buf);  //В Path0 записываем полученную строку
        ForceDirectories(Path0);//Создаем каталог, если его не существует
        ChDir(Path0); //Входим в него
        Path1=""; //Относительный путь равен пустой строке
      }
       
      //------------------------------------------------------------------------------
      //Функщия, которая выполняется после каждого сеанса кодирования и декодирования
       
      void end(void)
      {
        SpisokPtr prevPtr; //Указатель на предыдущий элемент списка
        tekPtr=headPtr; //Текущим элементом списка делаем первый
        while (tekPtr!=NULL) //Пока текущий элемент не равен NULL
        {
          prevPtr=tekPtr;  //Сохраняем указатель на текущий элемент в prevPtr
          tekPtr=tekPtr->nextPtr; //tekPtr переводим на следующий элемент
          free(prevPtr->filename); //Освобождаем память строки имени файла предыдущего
                                   //элемента списка
          free(prevPtr); //Освобождаем память от предыдущего элемента списка
        }
        headPtr=NULL; // headPtr устанавливаем в NULL
      }
       
      //------------------------------------------------------------------------------
      // Собственно адаптивное арифметическое кодирование
      // Входной параметр - имя выходного файла
      void encode (char *outfile)
      {
        int ch; //Переменная, в которую считывается очередной символ исходного
                //алфавита из входного файла
        int symbol;  //соответствующий ему символ рабочего алфавита
        start();   //вызоваем функцию start
        obhod();   //обходим все файлы каталога и подкаталогов
        Form1->ProgressBar1->Max=nf; //Делаем максимальное значение индикатора
                                     //состояния процесса равное количеству файлов
        Form1->ProgressBar1->Position=0;//Устанавливаем значение индикатора
                                        //состояния процесса в 0
        Form1->Label1->Visible=False;   //Делаем невидимой строку информации
        Form1->ProgressBar1->Visible=True;//Делаем видимым индикатор состояния процесса
        out = fopen ( outfile, "w+b"); //Открываем файл архива для перезаписи
        if (out == NULL)  // если файл не создается, то сообщаем об этом пользователю
        {
          Form1->Label1->Caption="Не получается создать файл архива!";
          Form1->ProgressBar1->Visible=False;
          Form1->Label1->Visible=True;
          return; //Завершаем процесс
        }
        fwrite(&nf,2,1,out); //Записываем в начало архива количество файлов
        //Записываем список файлов с относительными путями в начало архива
        tekPtr=headPtr; //Делаем первый элемент списка текущим
        while (tekPtr!=NULL) //Пока не достигнут конец списка
        {
          fprintf(out,"%s\n",tekPtr->filename);//Записываем имя файла с относительным
                                               //путем к нему в файл архива
          tekPtr=tekPtr->nextPtr;  //Переходим к следующему файлу в списке
        }
        start_model (); //Производим инициализацию адаптивной модели
        start_outputing_bits (); //Производим инициализацию побитового вывода
        start_encoding (); //Производим инициализация регистров границ и кода перед
                           //началом сжатия
        //Производим последовательное кодирование всех файлов списка                  
        tekPtr=headPtr; // Делаем первый элемент списка текущим
        while (tekPtr!=NULL) //Пока не достигнут конец списка
        {
          char infile[MAX_PATH];  //переменная, в которой хранится имя входного файла
          strcpy(infile,tekPtr->filename); //копируем в нее имя текущего файла списка
          tekPtr=tekPtr->nextPtr;          //переходим к следующему файлу списка
          in = fopen ( infile, "rb"); //открываем этот файл для чтения
          if (in == NULL) continue;  //если он не открывается, то продолжаем
          for (;;)  //Цикл с заранее неизвестным числом повторений
          {
            ch = getc (in); //считываем очередной символ исходного алфавита из файла
            if (ch == EOF) break; //если достигнут конец файла, то выходим из цикла
            symbol = char_to_index [ch]; //находим соответствующий ему символ рабочего алфавита
            encode_symbol (symbol); //кодируем этот символ
            update_model (symbol);  //обновляем модель очередным символом
          }
          encode_symbol (EOF_SYMBOL); //При выходе из цикла кодируем символ конца файла
          fclose (in); //Закрываем входной файл
          Form1->ProgressBar1->Position++; //Увеличиваем значение индикатора на 1
        }
        done_encoding (); //Производим завершение кодирования потока
        done_outputing_bits(); //Очистка буфера побитового вывода
        fclose (out);  //Закрываем файл архива
        end(); //вызываем функцию end
        Form1->ProgressBar1->Visible=False; //Прячем индикатор состояния процесса
        Form1->Label1->Caption="Архивация завершена"; //Выводим сообщение пользователю
        Form1->Label1->Visible=True; //Делаем его видимым
      }
       
      //------------------------------------------------------------------------------
      //Функция выделяющая из строки имени файла относительный путь к нему, и
      //создающая этот каталог, входной параметр - имя файла
      void makedir(char *filename)
      {
        if(strchr(filename,'\\')!=NULL) //Если имя файла содержит '\', то
        {
          char buf[MAX_PATH]; //Переменная, в которой будет происходить преобразование
                              //имени файла
          char *p; //вспомогательный указатель
          strcpy(buf,filename); //Копируем в buf имя файла
          p=strchr(buf,0); //запоминаем в p конец строки
          for(;*p!='\\';p--); //Уменьшаем p пока он не указывает на '\'
          *p=0; //Ставим на место '\' символ конца строки
          Path1=AnsiString(buf); //Делаем преобразованную строку относительным путем
          ForceDirectories(Path0+Path1); //Создаем такую директорию, если ее не существует  
        }
      }
       
      //------------------------------------------------------------------------------
      // Собственно адаптивное арифметическое декодирование,
      //входной параметр - имя файла архива
      void decode ( char *infile)
      {
        SpisokPtr tekPtr; //указатель на текущий элемент списка
        int symbol;  //Переменная, в которую считывается очередной  символ рабочего
                     //алфавита из файла архива
        int ch; //соответствующий ему символ исходного алфавита
        in = fopen ( infile, "rb"); //Открываем файл архива для чтения
        if (in == NULL) //Если он не открывается, то
        {      //выводим об этом сообщение пользователю
          Form1->Label1->Caption="Не получается открыть файл архива!";
          Form1->Label1->Visible=True; //Делаем его видимым
          Form1->ProgressBar1->Visible=False; //Скрываем индикатор состояния
          return; //Завершаем процесс
        }
        start(); //вызоваем функцию start
        fread(&nf,2,1,in);//Считываем количество файлов в архиве (первые 2 байта)
        Form1->ProgressBar1->Max=nf; //Делаем максимальное значение индикатора
                                     //состояния процесса равное количеству файлов
        Form1->ProgressBar1->Position=0;//Устанавливаем значение индикатора
                                        //состояния процесса в 0
        Form1->Label1->Visible=False;   //Делаем невидимой строку информации
        Form1->ProgressBar1->Visible=True;//Делаем видимым индикатор состояния процесса
        //Заносим список файлов в динамический список, выполняя количество чтений
        for(int i=0;i<nf;i++) //равное числу файлов в архиве
        {
          int dl; //переменная, в которой хранится длина строки имени файла
          char filename[MAX_PATH]; //массив, в котором хранится имя файла
          fgets(filename,MAX_PATH,in); //считываем в него очередную строку
          dl=strlen(filename); //выясняем ее длину
          strcpy(&filename[dl-1],"\0"); //убираем из имени файла лишние символы
          addfile(filename); //добавляем имя файла в динамический список
        };
        start_model (); //Производим инициализацию адаптивной модели
        start_inputing_bits (); //Производим инициализацию побитового ввода
        start_decoding ();  //Производим инициализацию регистров перед декодированием
                            //и загрузку начала сжатого сообщения
        tekPtr=headPtr; //Делаем первый элемент списка текущим
        makedir(tekPtr->filename); //выделяем из строки имени файла относительный путь
                             //к нему, и создаем этот каталог, если его не существует
        out = fopen ( tekPtr->filename, "w+b"); //Перезаписываем первый файл
        for (;;) //Цикл с заранее неизвестным числом повторений
        {
          symbol = decode_symbol ();//Декодируем очередной символ рабочего алфавита
          if (symbol == EOF_SYMBOL) //Если он равен символу конца файла, то
          {
            fclose (out); //Закрываем текущий файл
            Form1->ProgressBar1->Position++; //Увеличиваем значение индикатора на 1
            tekPtr=tekPtr->nextPtr; //Переходим к следующему элементу списка
            if (tekPtr==NULL) //Если достигнут конец списка, то
                break; //выходим из цикла
              else //иначе
              {
                makedir(tekPtr->filename); //выделяем из строки имени файла
          //относительный путь к нему, и создаем этот каталог, если его не существует
                out = fopen( tekPtr->filename, "wb"); //Перезаписываем текущий файл
                continue; //Продолжаем цикл
              }
          }
          ch = index_to_char [symbol]; //Очередному символу рабочего алфавита,
                                       //находим соответствующий символ исходного
          putc ( ch, out); //записываем его в выходной файл
          update_model (symbol); //обновляем модель очередным символом
        }
        fclose (in);  //Закрываем файл архива
        end();  //вызываем функцию end
        Form1->ProgressBar1->Visible=False; //Прячем индикатор состояния процесса
        Form1->Label1->Caption="Деархивация завершена"; //Выводим сообщение
        Form1->Label1->Visible=True; //Делаем его видимым
      }
      //------------------------------------------------------------------------------
      //Нажатие кнопки "Кодировать"
      void __fastcall TForm1::Button1Click(TObject *Sender)
      {
        char  outfile[MAX_PATH];  //Массив, в котором хранится имя выходного файла
        strcpy(outfile,LabeledEdit2->Text.c_str()); //Копируем в него имя файла,
                                       //введенное в строку ввода LabeledEdit2
        char *p=strchr(outfile,'.');//В переменной p сохраняем указатель на символ '.'
        if(p)                //если имя файла содержит точку, то
            strcpy(p,".ar"); //начиная с нее копируем строку ".ar"
          else strcat(outfile,".ar"); //иначе добавляем к имени файла строку ".ar"
        encode(outfile); //Вызываем функцию кодирования с получившимся именем файла
      }
      //------------------------------------------------------------------------------
      //Нажатие кнопки "Декодировать"
      void __fastcall TForm1::Button2Click(TObject *Sender)
      {
        char infile[MAX_PATH]; //Массив, в котором хранится имя входного файла
        strcpy(infile,LabeledEdit2->Text.c_str()); //Копируем в него имя файла,
                                       //введенное в строку ввода LabeledEdit2
        decode(infile); //Вызываем функцию декодирования с получившимся именем файла
      }
       
      //------------------------------------------------------------------------------
      //Нажатие кнопки выбора пути текущего каталога
      void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
      {
        AnsiString dir; //Строка, которая будет содержать путь к каталогу
        if (SelectDirectory("Укажите путь","",dir)) //Если был выбран путь, то
           LabeledEdit1->Text=dir; //заносим его в LabeledEdit1
      }
       
      //------------------------------------------------------------------------------
      //Нажатие кнопки выбора файла архива
      void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
      {
        SaveDialog1->InitialDir=LabeledEdit1->Text; //В InitialDir устанавливаем
                                                    //LabeledEdit1
        if (SaveDialog1->Execute()) //Если был выбран файл архива, то
           LabeledEdit2->Text=SaveDialog1->FileName; //заносим его имя в LabeledEdit2
      }
       
      //------------------------------------------------------------------------------
      //Нажатия кнопки "О программе"
      void __fastcall TForm1::N1Click(TObject *Sender)
      {
        Form1->Hide();      //Прячем главную форму
        Form2->ShowModal(); //Показываем модально окно "О программе"
        Form1->Show();      //Показываем главную форму
      }
      //------------------------------------------------------------------------------

    Прикреплённый файлПрикреплённый файлUnit1.zip (9,74 Кбайт, скачиваний: 13)
    Подпись выключена.
      Господи, ну откуда в BC31 взялась VCL?
      Одни с годами умнеют, другие становятся старше.
        Даже "древние" компиляторы имели отладчик.
        Если не имели то то вывод на экран/поток/файл (my.exe>my.txt) никто не запрещал.
        Цель - ничто , процесс - все.
          Цитата Qraizer @
          Господи, ну откуда в BC31 взялась VCL?

          Господи, ну откуда "автор" ЭТО срисовал??? :wacko:
          ...one shot at glory in the crossfire overhead...© JP
            Цитата LMM @
            Господи, ну откуда "автор" ЭТО срисовал???

            Это сомбиоз версий или одно из двух?
            Цель - ничто , процесс - все.
              Это написано на Borland C++ Builder с кучей специфичного для Builder синтаксиса. Само собой, старик BC31 такого не знает: ни ресурсных прагм, ни RTTI-маркеров. Сконвертировать это в BC31 будет весьма затратно по времени.

              Господи, дело к весне? Предзащита, всё такое...
              Сообщение отредактировано: Mr.Delphist -
              Windows as usual - my "wau" Windows experience
              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script Execution time: 0,1498 ]   [ 20 queries used ]   [ Generated: 21.08.18, 19:28 GMT ]