Архиватор своими руками

Архиватор своими руками Намой взгляд, наиболее удобной средой разработки программ является Visual Studio 2008 от Microsoft также считает и www.piter-it.ru www.piter-it.ru, потому что она наиболее адекватно отражает суть окружающей действительности программного мира и находится, так сказать, в авангарде современныхтенденций высоких технологий.

Дистрибутив студии вы можете скачать с официального сайта Microsoft (http://www. microsoft.com/express/download/#weblnstall). Размер дистрибутива весьма внушительный – 938 Мб.

Итак, будем считать, что программа у вас есть, и вы ее установили на свой компьютер. Для начала нам необходимо создать проект. Для этого запускаем студию и жмем – создать новый проект (screen 1). В появившемся окне в графе Project type (тип проекта) выбираем VisualC++ -> Win32, в графе Templates -> Win32 Console Application. В поле Name и Solution name – забиваем название проекта, у меня это freqAnal (частотный анализаторХвсгееп 2). В следующем окне жмем NEXT.

Далее в поле Additional option ставим галочку в чек-бокс Empty project и жмем FINISH. В появившемся окне находим Solution Explorer, жмем правой кнопкой по Header Files->Add->New Item…(screen 3), далее выбираем категорию Code, тип С++ File (.cpp), имя – я забил по названию проекта, но можно иначе (screen 4).

Для начала немного теории: чтобы писать архиватор, необходимо иметь представление о том, как он работает.

[i]Архиватор можно разделить на:[/i]

– частотный анализатор;
– построение «дерева» Хаффмана;
– непосредственно компрессия.

0 назначении каждого блока будет рассказываться в следующих статьях.
Кратко принцип действия можно описать так – исходя из частоты появления символа можно закодировать его разным числом бит, начиная от 1-го и заканчивая в зависимости от количества используемых символов. Напомню, что в классическом представлении ASCII таблицы – каждый символ кодируется 8 битами или 1 байтом.

Приступим к формированию кода. Напомню, что в C/C++ структура программы выглядит следующим образом:

1 # include <библиотека>
2 тип main (тип) {
3......//текст программы
4 return 0; }

Где 1 -я строка подключает внешнюю библиотеку, 2-я объявляет тип возвращаемых данных «тип» из программы инициализированной функцией «main» с входными параметрами «тип». Ну вот, с основными понятиями разобрались, идём дальше.

Чтение

Чтобы проанализировать частоту встречаемости символа в файле, нам нужен сам файл и счётчик символов:

int freg [256]={0};// массив, который выполняет роль счётчика
FILE fileOPN;//указатель на файл.

Отлично, помещаем инициализацию в тело функций «main».

Открываем файл, аточнее, инициализируем переменную и ассоциируем её с файлом.

fileOPN=fopen ("С:\\\\путь", "rb");

Слэш необходимо дублировать, иначе компилятор воспримет его как спецсимвол.

«rb»- читать в битах, чтоб наверняка.

Теперь строим цикл чтения файла и подсчета частоты. Для этого введем ещё одну переменную того же типа, что и массив, назовем ee«symb».

В нем мы будем читать байт из файла и проверять, не закончился ли файл «EOF».

int symb=0;// обязательно обнуляем.
white ((symb=fgetc(fileOPN))!=EOF)
{
freg[symb]++: }

Тут всё понятно, пока «symb» не равен концу файла, мы присваиваем элементу массива «symb» +1. Так как все символы закодированы числами от 0 до 255 – как раз наш массив.

Если вы сейчас запустите вашу программу, то она уже будет рабочим счетчиком частоты, но работать она будет некорректно. И постоянно будет вызывать ошибку переполнения буфера.

Разбираемся. Дело втом, что символы у нас кодируются в интервале от 0 до 127 и -128 до -1. Прошу заметить, что после 127 идёт -128, это ключевой момент нашего дальнейшего рассуждения. Выход из ситуации прост до безумия – надо поставить проверку и перевести значения в положительный диапазон.

if (symb<0) symb=symb*(-1)+127;

Просто? Ещё бы! Существует и более быстрый способ, но его вы можете найти сами.

Это мы напишем в основном условии, и проверка нам не понадобится.

Всё! Основной блок готов – проверяйте. Для компиляции нажмите F5.

[i]Сразу вопрос – а как проверить?[/i]

А вот тут мы переходим к следующей части анализатора-запись полученных данных в файл.

Запись

Перед тем как начать записывать в файл, закрываем открытый, чтобы случайно его не покалечить.

fclose(fileOPN);

Теперь создадим новый файл для записи.

fileOPN=fopen("nyrb", "wb"); 

«wb» – запись битовая.

Для записи в файл используем функцию fputs(string, fileOPN).

Где string – массив из 20 элементов типа char, он предназначен для перевода числового значения в символы, т.к. в файл мы можем записывать только символы.

Функция перевода числа в символьную строку выглядит следующим образом itoa(freq[i],string, 10);// 10 – это разрядность числа, т.е. десятичная система счисления.

Цикл записи у нас будет выглядеть следующим образом:

for(inti=0;i<256;i++)
{
_itoa(freq[i], string, 10): fputs(string,fileOPN);
fclose(fileOPN);

Ну вот и все – частотный анализатор готов, остались нюансы. Предлагаю их для самостоятельного решения:

1. Программа, конечно, работает, но очень медленно – как ее ускорить? Даю наводку – проблема кроется в цикле чтения файла. Вторая подсказка – воспользуйтесь функцией чтения строки -fgets(buff ,lenght,file). buff – куда читать, lenght – сколько читать, file – откуда читать, конец файла в этом случае будет обозначаться NULL.

2. В файл мы записали только числа, как добавить туда буквы, которым принадлежит частота (например «а = 322533»)? А также напишите фильтр, позволяющий выводить в файл только встречающиеся символы, а не все подряд, как это у нас получилось и, соответственно, в отдельных строках.

3. Попробуйте отсортировать частоты в порядке убывания, т.е. сверху – самые частые, а снизу самые редкие символы.

В следующем номере вы найдете ответ на эти вопросы, а также получите описание метода быстрой сортировки.

Ну вот, а теперь полный листингтого, что у нас должно получиться:

#include <stdio.h> #include<stdlib.h> #include <time.h> int main (void) {
FILE *fileOPN: intfreq[256]={0}: int symb=0; charstring[20]={0};
fileOPN=fopen ("С:\\\\путь к файлу для чтения".
"rb");
white ((symb=fgetc(fileOPN))!=EOF) {
if (symb<0)
symb=symb*(-1)+127: freg[symb]++;
}
fclose(fileOPN);
fileOPN=fopen("nyrb к новому файлу", "wb"):
for(inti=0;i<256;i++)
{
_itoa(freq[i],string, 10): fputs(string,fileOPN);
}
fclose(fileOPN): return 0;
t

Если в процессе разработки у вас возникнут вопросы – смело шлите их на электронный адрес secret@gmi.ru. Исходник программы можно найти здесь – http://gmi. ru/fc_img/soft/freqAnal.cpp.

Добавить комментарий