Міністерство освіти і науки України
Національний університет "Львівська політехніка"
Кафедра "Інформаційні системи та мережі "
К У Р С О В А Р О Б О Т А
з дисципліни "Проблемно-орієнтовані мови програмування"
на тему:
"Програма-архіватор"
ЛЬВІВ-2006
Зміст
Вступ 3
1. Формулювання задачі 4
2. Методи та засоби розв’язування задачі 5
3. Алгоритми розв'язування задачі 11
4. Опис програми на мові C/C++ 16
5. Технологія програмування, виконання та відлагодження програми 18
6. Інструкція користувачеві 19
7. Контрольний приклад та аналіз результатів комп'ютерної реалізації програми 21
Висновки 22
Література 23
Додаток 1. Текст програми на мові С 34
Вступ
Метою виконання курсової роботи є закріплення теоретичних знань та практичних навичок програмування, набутих при вивченні дисципліни "Проблемно-орієнтовні мови програмування". В ході виконання розрахункової роботи я навчився самостійно працювати з літературою, розробляти алгоритми та програми на мові програмування Turbo C. Завдяки роботі з невідомими функціями, операторами та іншими складовими мови Сі, та їх самостійному вивченню я розвинув проблемно-орієнтоване мислення.
Усі основні пріоритети розрахункової роботи я виконав, закріпивши, тим самим, знання, набуті під час вивчення дисципліни, а також отримані під час самостійної роботи.
1. Формулювання задачі
Виконання курсової роботи передбачає розробку програми-архіватора, що буде виконувати дві основні функції:
стиснення довільного двійкового чи текстового дискового файла обраним методом архівування;
розархівування попередньо стиснутого файлу.
Вхідним файлом в першому випадку може бути будь-який текстовий чи двійковий файл. Єдина вимога до файла – він повинен мати розмір не більше 2 ГБ (це робиться для коректної передачі довжини файлу). В другому випадку на вхід обов’язково подавати файл, попередньо стиснутий розроблюваною програмою.
2. Методи та засоби роз’язування задачі
Характерною особливістю більшості типів даних є їх надлишковість. Ступінь надлишковості даних залежить від типу даних. Наприклад, для відеоданих ступінь надлишковості в декілька разів більша ніж для графічних даних, а ступінь надлишковості графічних даних, у свою чергу, більша за ступінь надлишковості текстових даних. Іншим фактором, що впливає на ступінь надлишковості є прийнята система кодування. Прикладом систем кодування можуть бути звичайні мови спілкування, які є ні чим іншим, як системами кодування понять та ідей для висловлення думок. Так, встановлено, що кодування текстових даних за допомогою засобів української мови дає в середньому надлишковість на 20-25% більшу ніж кодування аналогічних даних засобами англійської мови.
Для людини надлишковість даних часто пов'язана з якістю інформації, оскільки надлишковість, як правило, покращує зрозумілість та сприйняття інформації. Однак, коли мова йде про зберігання та передачу інформації засобами комп'ютерної техніки, то надлишковість відіграє негативну роль, оскільки вона приводить до зростання вартості зберігання та передачі інформації. Особливо актуальною є ця проблема у випадку необхідності обробки величезних обсягів інформації при незначних об'ємах носіїв даних. У зв'язку з цим постійно виникає проблема позбавлення надлишковості або стиснення даних. Коли методи стиснення даних застосовуються до готових файлів, то часто замість терміну "стиснення даних" вживають термін "архівування даних", стиснений варіант даних називають архівом, а програмні засоби, що реалізують методи стиснення називаються архіваторами.
В залежності від того, в якому об'єкті розміщені дані, що підлягають стисненню розрізняють:
Стиснення (архівування) файлів: використовується для зменшення розмірів файлів при підготовці їх до передавання каналами зв'язку або до транспортування на зовнішніх носіях малої ємності;
Стиснення (архівування) папок: використовується як засіб зменшення обсягу папок перед довготерміновим зберіганням, наприклад, при резервному копіюванні;
Стиснення (ущільнення) дисків: використовується для підвищення ефективності використання дискового простору шляхом стиснення даних при записі їх на носії інформації (як правило, засобами операційної системи).
Існує багато практичних алгоритмів стиснення даних, але всі вони базуються на трьох теоретичних способах зменшення надлишковості даних. Перший спосіб полягає в зміні вмісту даних, другий - у зміні структури даних, а третій - в одночасній зміні як структури, так і вмісту даних.
Якщо при стисненні даних відбувається зміна їх вмісту, то метод стиснення є незворотнім, тобто при відновленні (розархівуванні) даних з архіву не відбувається повне відновлення інформації. Такі методи часто називаються методами стиснення з регульованими втратами інформації. Зрозуміло, що ці методи можна застосовувати тільки для таких типів даних, для яких втрата частини вмісту не приводить до суттєвого спотворення інформації. До таких типів даних відносяться відео- та аудіодані, а також графічні дані. Методи стиснення з регульованими втратами інформації забезпечують значно більший ступінь стиснення, але їх не можна застосовувати до текстових даних. Прикладами форматів стиснення з втратами інформації можуть бути: JPEG (Joint Photographic Experts Group) для графічних даних; MPG - для для відеоданих; MP3 - для аудіоданих.
Якщо при стисненні даних відбувається тільки зміна структури даних, то метод стиснення є зворотнім. У цьому випадкові з архіву можна відновити інформацію повністю. Зворотні методи стиснення можна застосовувати до будь-яких типів даних, але вони дають менший ступінь стиснення у порівнянні з незворотними методами стиснення. Приклади форматів стиснення без втрати інформації: GIF (Graphics Interchange Format), TIFF (Tagged Image File Format) - для графічних даних; AVI - для відеоданих; ZIP, ARJ, RAR, CAB, LH - для довільних типів даних. Існує багато різних практичних методів стиснення без втрати інформації, які, як правило, мають різну ефективність для різних типів даних та різних обсягів. Однак, в основі цих методів лежать три теоретичних алгоритми:
алгоритм RLE (Run Length Encoding);
алгоритми групи KWE(KeyWord Encoding);
алгоритм Хафмана.
Алгоритм RLE
В основі алгоритму RLE лежить ідея виявлення послідовностей даних, що повторюються, та заміни цих послідовностей більш простою структурою, в якій вказується код даних та коефіцієнт повторення. Наприклад, нехай задана така послідовність даних, що підлягає стисненню:
1 1 1 1 2 2 3 4 4 4
В алгоритмі RLE пропонується замінити її наступною структурою: 1 4 2 2 3 1 4 3, де перше число кожної пари чисел -це код даних, а друге - коефіцієнт повторення. Якщо для зберігання кожного елементу даних вхідної послідовності відводиться 1 байт, то вся послідовність займатиме 10 байт пам'яті, тоді як вихідна послідовність (стиснений варіант) займатиме 8 байт пам'яті.
Чим менше значення коефіцієнта стиснення, тим ефективніший метод стиснення. Зрозуміло, що алгоритм RLE буде давати кращий ефект стиснення при більшій довжині послідовності даних, що повторюється. У випадкові розглянутого вище прикладу, якщо вхідна послідовність матиме такий вигляд: 1 1 1 1 1 1 3 4 4 4, то коефіцієнт стиснення буде рівний 60%. У зв'язку з цим найбільша ефективність алгоритму RLE досягається при стисненні графічних даних (особливо для однотонових фонових зображень).
Алгоритми групи KWE
В основі алгоритму стиснення за ключовими словами покладено принцип кодування лексичних одиниць групами байт фіксованої довжини. Прикладом лексичної одиниці може бути звичайне слово. На практиці, в ролі лексичних одиниць вибираються послідовності символів, що повторюються, які кодуються ланцюжком символів (кодом) меншої довжини. Результат кодування зводиться в таблицю, утворюючи так званий словник.
Існує досить багато реалізацій цього алгоритму, серед яких найбільш поширеними є алгоритм Лемпеля-Зіва (алгоритм LZ) та його модифікація алгоритм Лемпеля-Зіва-Велча (алгоритм LZW). Словником в даному алгоритмі є потенційно нескінченний список фраз. Алгоритм починає роботу з майже пустого словника, що містить тільки один закодований рядок, так званий NULL-рядок. Коли зчитується черговий символ вхідної послідовності даних, він додається до поточного рядка. Процес продовжується доти, поки поточний рядок відповідає якій-небудь фразі з словника. Але рано або пізно поточний рядок перестає відповідати якій-небудь фразі словника. У цей момент, коли поточний рядок являє собою останній збіг зі словником плюс щойно прочитаний символ повідомлення, кодер видає код, що складається з індексу збігу і наступного за ним символа, що порушив збіг рядків. Крім того, нова фраза, що складається з індексу збігу і наступного за ним снмвола, додається в словник. У наступний раз, коли ця фраза з'явиться в повідомленні, вона може бути використана для побудови більш довгої фрази, що підвищує міру стиснення інформації.
Алгоритм LZW побудований навколо таблиці фраз (словника), яка відображає рядки символів стиснуваного повідомлення в коди фіксованої довжини. Таблиця володіє так званою властивістю передування, тобто для кожної фрази словника, що складається з деякої фрази w і символа К фраза w також міститься в словнику. Якщо всі частинки словника повністю заповнені кодування перестає бути адаптивним (кодування відбувається виходячи з вже існуючих в словнику фраз).
Алгоритми стиснення цієї групи найефективніші для текстових даних великих обсягів і малоефективні для файлів малих розмірів (за рахунок необхідності зберігання словника).
Алгоритм Хафмана
В основі алгоритму Хафмана лежить ідея кодування бітовими групами. Спочатку проводиться частотний аналіз вхідної послідовності даних, тобто встановлюється частота входження кожного символу, що зустрічається у ній. Після цього символи сортуються по спаданню частоти входження.
Основна ідея полягає в наступному: чим частіше зустрічається символ, тим меншою кількістю біт він кодується. Результат кодування зводиться в словник, що необхідний для декодування.
Розглянемо простий приклад, що ілюструє роботу алгоритму Хафмана. Нехай задано текст, в якому літера 'А' входить 10 разів, літера 'B' - 8 раз, 'C'- 6 разів , 'D' - 5 разів, 'E' і 'F' - по 4 рази. Тоді один з можливих варіантів кодування за алгоритмом Хафмана наведений у таблиці 1.
Таблиця 1.
Символ
Частота входження
Бітовий код
A
10
00
B
8
01
C
6
100
D
5
101
E
4
110
F
4
111
Як видно з таблиці 1, розмір вхідного тексту до стиснення рівний 37 байт, тоді як після стиснення - 93 біт, тобто майже 12 байт (без врахування довжини словника). Коефіцієнт стиснення рівний 32%. Алгоритм Хафмана універсальний, тобто його можна застосовувати для стиснення даних будь-яких типів, але він малоефективний для файлів малих розмірів (за рахунок необхідності зберігання словника).
На практиці програмні засоби стиснення даних синтезують ці три "чистих" алгоритми, оскільки їх ефективність залежить від типу та обсягу даних. У таблиці 2 наведені найпоширеніші формати стиснення та відповідні їм програми-архіватори, що використовуються на практиці.
Таблиця 2.
Формат стиснення
Операційна система MS DOS
Операційна система Windows
Програма архівування
Програма розархівування
Програма архівування
Програма розархівування
ARJ
Arj.exe
Arj.exe
WinArj.exe
WinArj.exe
RAR
Rar.exe
Unrar.exe
WinRar.exe
WinRar.exe
ZIP
Pkzip.exe
Pkunzip.exe
WinZip.exe
WinZip.exe
Крім того, сучасні архіватори надають користувачеві повний спектр послуг для роботи з архівами, основними з яких є:
створення нового архіву;
додавання файлів в існуючий архів;
розпакування файлів з архіву;
створення архівів, що саморозпаковуються (self-extractor archive);
створення розподілених архівів фіксованих розмірів для носіїв малої ємності;
захист архівів паролями від несанкціонованого доступу;
перегляд вмісту файлів різних форматів без попереднього розархівування;
пошук файлів і даних всередині архіву;
перевірка на віруси в архіві до розпакування;
вибір та налаштування коефіцієнта стиснення.
Матеріал з файлу http://www.victoria.lviv.ua
Для виконання курсової роботи я вибрав алгоритм Хафмена, зокрема його модифікація, що використовує канонічне дерево.
3. Алгоритми розв'язування задачі
Алгоритм Хафмена працює в два обходи:
в першому проводиться дослідження вхідного файлу і побудова дерева Хафмена – бінарного дерева, відповідає одному з оптимальних ентропійних кодів для вхідного файлу, в даній програмі початкове дерево буде перетворене в так зване канонічне дерево (одною з особливостей якого є мінімальна надлишковість, а отже найкоротший опис(код));
в другому відбувається кодування вхідного файлу кодом Хафмена з створеного дерева.
На основі вищесказаного можна створити такий алгоритми для функцій стиснення і деархівації:
АЛГОРИТМ КОМПРЕСІЇ:
Прочитати довжину вхідного файлу та зберегти її в архівний;
ОБХІД 1: побудувати таблицю частот вживання кожного символу в вхідному файлі;
На основі таблиці сформувати список початкових вузлів бінарного дерева для кожного символу з ненульовою частотою вживання, що буде містити інформацію про код символу і його частоту вживання;
Побудувати дерево Хафмена таким чином:
ПОКИ (в списку більше одного вузла) РОБИТИ
ПОЧАТОК
Вилучити зі списку два вузла два вузли з найменшою вагою;
Сформувати з вилучених вузлів новий вузол, вагою якого вважати суму ваг вузлів-синів, і додати його до списку;
КІНЕЦЬ;
Побудувати код дерева Хафмена, а саме елементу масиву, адреса якого дорівнює коду символу, присвоїти висоту гілки дерева, що відповідає символу;
Зберегти код дерева в архівний файл;
Побудувати масив, елементами якого будуть лінійні списки листків дерева Хафмена, що мають однакову висоту (будується на основі коду дерева);
Будується канонічне дерево Хафмена таким чином:
Обходиться з кінця масив з п. 7, до найпершого елемента виключно. Коли зустрічається непорожній список, вибирається два елемента списку, додаються в новий вузол дерева Хафмена і додається в список, сусідній з поточним і ближчий до початку, і так до вичерпання поточного списку.
Побудувати масив покажчиків на листя дерева Хафмена: елемент з індексом Х буде показувати на лист, що відповідатиме символу Х;
ОБХІД 2: кодування вхідного файлу кодом Хафмена:
Для кожного символу виводиться в вихідний потік послідовність бітів, що відповідає гілці від кореня до відповідного символу листа.
АЛГОРИТМ ДЕКОМПРЕСІЇ:
Зчитати довжину оригінального файлу з архівного файлу
Зчитати код дерева з архівного файлу;
Побудувати масив, елементами якого будуть лінійні списки листків дерева Хафмена, що мають однакову висоту (будується на основі коду дерева);
Будується канонічне дерево Хафмена таким чином:
Обходиться з кінця масив з п. 7, до найпершого елемента виключно. Коли зустрічається непорожній список, вибирається два елемента списку, додаються в новий вузол дерева Хафмена і додається в список, сусідній з поточним і ближчий до початку, і так до вичерпання поточного списку.
Розкодування вхідного файлу кодом Хафмена:
Іти від кореня по дереву Хафмена до листа, символ, відповідний якому символ записати у вихід, повторити за кількістю символі оригінального файлу.
Блок-схема основної функції програми неведена нижче
Блок-схема функції void run(int activekey)
4. Програма та її опис
4.1. Назва програми
MYA.exe, huffmen.exe
Примітка: через те, перериваня, що використовуються в MYA.exe, коректно працювали лише в компіляторі Turbo C++ IDE 3.0, а алгоритм стиснення, що активно використовував динамічну пам'ять, тільки в середовищі Borland C++ Builder 6, програму довелося розділити на два виконувані файли.
4.2. Призначення програми
Програма призначена для компресії та декомпресії текстових та двійкових дискових файлів. Вона стискає файли, які володіють ентропійними надлишковостями. Файли, позбавлені таких надлишковостей, програма стиснути ефективно не може. Ще програма не працює з файлами, довшими за 2ГБ.
Програма MYA.exe забезпечує інтерфейс, необхідний за вимогами.
Програма huffmen.exe виконує архівацію і де архівацію за викликами програми MYA.exe.
4.3. Мови програмування, на яких написана програма
Програма написана та реалізована на мові програмування C, з коментарями в стилі С++, в двох середовищах, Turbo C++ IDE 3.0 (MYA.exe) і Borland C++ Builder 6 (huffmen.exe). Текст програми розміщено в Додатку 1.
4.4. Логічна структура програми
Взаємодія користувача з програмним середовищем відбувається через програму MYA.exe, яка сворює візуальний інтерфейс. Вона вводить імена файлів і вибирає режим роботи. Потім вона викликає програму huffmen.exe, якій в якості параметрів командного рядка передає рижим роботи і імена файлів. Остання викнує компресію або декомпресію вибраних файлів.
Програмі MYA.exe виводить графічний інтерфайс програми і містить цикл, що постійно опитує клавіатуру і мишу, очікуючи дій користувача.
Програма huffmen.exe в залежності від вмісту командного рядка виконує компресію або декомпресію файлів, вказаних в командному рядку, викликаючи функції hcompress1 і hexpand1.
4.5. Вхідні та вихідні дані
В розділах "Вхідні дані" та "Вихідні дані" вказуються способи організації
даних, їх формати, оголошення, способи кодування та носії.
Для стиснення як вхідні дані підходить будь-який файл, не довший за 2 ГБ, виходом буде файл, що міститиме таку інформацію про оригінальний файл в такому форматі:
4 біти – довжина оригінального файлу;
256 біт – опис канонічного дерева Хафмена;
послідовність кодів символів оригінального файлу;
Для деархівації потрібен файл, попередньо стиснений цією ж програмою, на виході отримується файл, ідентичний за змістом оригінальному.
4.6. Програмні засоби, необхідні для реалізації програми
Розробка програми у середовищах Borland C++ Builder 6 і Turbo C++ IDE 3.0, зі стандартними редактором тексту, компілятором, редактором зв'язків, завантажувачем коду програми, відлагоджувачем. Я працював в операційній системі MS Windows XP, в режимі емуляції MSDOS. Працювати програма повинна під усіма операційними системами лінійки Windows та DOS.
4.7. Технічні засоби, необхідні для реалізації програми
Для реалізації програми потрібний IBM-сумісний комп’ютер, з мінімальними параметрами необхідними для функціонування операційної системи Microsoft Windows XP.
5. Технологія програмування, виконання та відлагодження програми
Опишемо вибрані технології програмування, виконання та відлагодження програми на комп’ютері.
Технологія програмування
При створенні програми була використана технологія модульного програмування.
Технологія виконання програми
Для запуску програми треба викликати виконуваний файл програми MYA.exe з параметром, що задає шлях до файла huffmen.exe.
Можна прямо викликати програму huffmen.exe з такими аргументами:
c [вхідний файл] [вихідний файл] – для стиснення
e [вхідний файл] [вихідний файл] – для деархівування
Технологія відлагодження програми
Для виявлення, аналізу та виправлення помилок програми я використовував ехо-вивід вхідних даних та вивід проміжних даних у контрольних точках програми, використовуючи стандартні (вбудовані) відлагоджувачі середовищ програмування.
6. Інструкція користувачеві
Для запуску програми треба викликати виконуваний файл програми MYA.exe з параметром, що задає шлях до файла huffmen.exe. Ви отримаєте такий інтерфейс:
Далі можна виконати такі дії:
- редагувати команду, що викликається перед викликом команд стиснення і декомпресії, ім’я вхідного чи вихідного файла,
- виконати компресію чи декомпресію. В такому випадку після появи діалогового вікна треба дочекатися, поки напис IN PROGRESS… внизу вікна зміниться на COMPLITE,
- вийти з програми.
Можна прямо викликати програму huffmen.exe, що безпосередньо викону архівацію і деархівацію з такими аргументами:
c [вхідний файл] [вихідний файл] – для стиснення
e [вхідний файл] [вихідний файл] – для деархівування
Відповідний скріншот для режиму архівації:
Відповідний скріншот для режиму деархівації:
7. Контрольний приклад та аналіз результатів комп'ютерної реалізації програми
Для перевірки вірності і ефективності роботи програми було підібрано групу файлів. Типи файлів, їх розміри до стиснення та після наведені в таблиці 3.
Таблиця 3.
Тип файлу
Розмір оригінального файлу
Розмір архівованого файлу
Відношення
Текстовий документ в форматі RTF
302 954
164 232
54,21%
Текстовий документ в форматі TXT
408 342
245 108
60,03%
Текстовий документ в форматі PDF
995 004
994 453
99,94%
Малюнок в форматі BMP
2 611 254
2 424 882
92,86%
Коректність відтворення оригінального файлу перевірялась і підтвердилась.
Загалом випробовування програми дали позитивний результат, стиснення для файлів з ентропійним надлишком дало непогані результати.
Висновки
Як результат виконання курсової роботи я опрацював весь теоретичний матеріал, наданий під час лекцій, а також додаткову літературу, необхідну для самостійної роботи. Серед здобутих знань та навичок можу виділити вміння працювати з мишкою.
Мною було розроблено програму на мові Cі, яка виконує поставлену задачу згідно розробленого алгоритму, містить зручний інтуїтивно зрозумілий інтерфейс. Під час опрацювання літератури, я вивчив нові функції, для програмування в середовищі Borland С.
Список літератури
1. Методичні вказівки до курсової роботи з дисциплiни "Проблемно-орієнтовані мови програмування" для студентів спеціальності “Інтелектуальні системи прийняття рішень” / Укл. П.О.Кравець. - Львів: Видавництво Національного університету “Львівська політехніка”, 2005. - 18 с.
2. Методичні вказівки до лабораторних робіт з дисциплiни "Проблемно-орієнтовані мови програмування" для студентів базового напрямку 0804 “Комп’ютерні науки” / Укл. Кравець П.О. – Львів: Видавництво Національного університету „Львівська політехніка”, 2005. – 111 с.
3. Техніка програмування мовою Сі: Навч. посібник / Проценко В. С., Чаленко П. Й., Ставровський А. Б. – К. : Либідь, 1993 – 244 с.
4. Язык программирования C. Лекции и упражнения. Учебник: Пер. с англ. / Стивен Прата – СПб.: ООО «ДиаСофтЮП», 2002. – 896 с.
5. Техника программирования на турбо Си. / Ал. Стивенс (c) пеpевод на pусский язык AcademySoft, 1989.
Додаткові джерела: інтернет.
Додаток 1. Текст програми на мові С
Файл MYA.CPP
// Основна програма
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <process.h>
#include <dos.h>
#include <alloc.h>
#include "INTRFACE.H"
#include "HELP.H"
#define NF 8
#define NK 7
char str[3][256]= // Тексові поля - команда, вхідний та вихідний файл
{"cd d:\\code\\edu", "in.bin", "out.bin"},
*PATH; // Шлях до зовнішного файлу архіватора
Field field[NF]={ // Поля
{ " MYA - MY ARCHIVER ", 1, 1, 80, 24, WHITE, WHITE, 1, 1 },
{ "Command", 3, 3, 66, 4, BLACK, WHITE, 1, 0 },
{ "Input file", 3, 7, 66, 4, BLACK, WHITE, 1, 0 },
{ "Output file", 3, 11, 66, 4, BLACK, WHITE, 1, 0 },
{ str[0], 4, 4, 64, 2, WHITE, BLUE, 0, 0 },
{ str[1], 4, 8, 64, 2, WHITE, BLUE, 0, 0 },
{ str[2], 4, 12, 64, 2, WHITE, BLUE, 0, 0 },
{ "Actions:", 4, 16, 64, 2, BLACK, WHITE, 0, 0 }
};
Key key[NK]={ // Кнопки
{ "Edit", 70, 4, 7, 1 },
{ "Edit", 70, 8, 7, 1 },
{ "Edit", 70, 12, 7, 1 },
{ "Compress", 14, 16, 12, 1 },
{ "Expand", 14, 18, 12, 1 },
{ "Help", 14, 20, 12, 1 },
{ "Exit", 14, 22, 12, 1 }
};
//------------------------------------------------------------------------------
// draw - виводить екран
// параметри:
// activeKey - номер активної кнопки
//------------------------------------------------------------------------------
void draw(int activekey)
{
int i;
textcolor(YELLOW);
textbackground(BLACK);
clrscr();
gotoxy(1, 25);
cputs("UP, DOWN - Move ENTER - Select ESC - Exit");
for(i=0; i<NF; i++)
drawField(&field[i]);
for(i=0; i<NK; i++)
drawKey(&key[i], i==activekey?1:0);
}
//------------------------------------------------------------------------------
// edit - редагувати текстове поле, вводить нове значення в
// field[activekey+4].t
// параметри:
// activeKey - номер активної кнопки
//------------------------------------------------------------------------------
void edit(int activekey)
{
window(field[activekey+4].x, field[activekey+4].y,
field[activekey+4].x+field[activekey+4].dx-1,
field[activekey+4].y+field[activekey+4].dy-1);
textcolor(RED);
textbackground(GREEN);
clrscr();
cursor_on();
gets(field[activekey+4].t);
cursor_off();
draw(activekey);
window(1, 1, 80, 25);
}
//------------------------------------------------------------------------------
// compress - компресія, використовується зовнішня програма huffmen.exe
// параметри:
// finname - вхідний файл
// foutname - вихідний файл
//------------------------------------------------------------------------------
void compress(char *finname, char *foutname)
{
char buff[600]="";
FILE *fin, *fout;
Field report[7]={
{ "COMPRESSION", 10, 4, 61, 17, WHITE, WHITE, 1, 1 },
{ "Input file", 12, 6, 57, 5, BLACK, WHITE, 1, 0 },
{ "Output file", 12, 12, 57, 5, BLACK, WHITE, 1, 0 },
{ finname, 13, 7, 55, 3, WHITE, BLUE, 0, 0 },
{ foutname, 13, 13, 55, 3, WHITE, BLUE, 0, 0 },
{ "IN PROGRESS...", 13, 18, 25, 1, BLACK, WHITE, 0,
0 },
{ "COMPLITE", 13, 18, 25, 1, BLACK, WHITE, 0,
0 }
};
for(int i=0; i<6; i++)
drawField(&report[i]);
strcat(buff, PATH);
strcat(buff, "huffmen.exe c ");
strcat(buff, finname);
strcat(buff, " ");
strcat(buff, foutname);
system(buff);
drawField(&report[6]);
OnError:
fcloseall();
getch();
cursor_off();
}
//------------------------------------------------------------------------------
// compress - декомпресія, використовується зовнішня програма huffmen.exe
// параметри:
// finname - вхідний файл
// foutname - вихідний файл
//------------------------------------------------------------------------------
void expand(char *finname, char *foutname)
{
char buff[600]="";
FILE *fin, *fout;
Field report[7]={
{ "EXPANDING", 10, 4, 61, 17, WHITE, WHITE, 1, 1 },
{ "Input file", 12, 6, 57, 5, BLACK, WHITE, 1, 0 },
{ "Output file", 12, 12, 57, 5, BLACK, WHITE, 1, 0 },
{ finname, 13, 7, 55, 3, WHITE, BLUE, 0, 0 },
{ foutname, 13, 13, 55, 3, WHITE, BLUE, 0, 0 },
{ "IN PROGRESS...", 13, 18, 25, 1, BLACK, WHITE, 0, 0 },
{ "COMPLITE", 13, 18, 25, 1, BLACK, WHITE, 0, 0 }
};
for(int i=0; i<6; i++)
drawField(&report[i]);
strcat(buff, PATH);
strcat(buff, "huffmen.exe e ");
strcat(buff, finname);
strcat(buff, " ");
strcat(buff, foutname);
system(buff);
drawField(&report[6]);
OnError:
fcloseall();
getch();
cursor_off();
}
//------------------------------------------------------------------------------
// run - виконання функції, повязаної з кнопкою activekey
// параметри:
// activeKey - номер активної кнопки
//------------------------------------------------------------------------------
void run(int activekey)
{
mouse_off();
switch(activekey)
{
case 0: case 1: case 2: edit(activekey); break;
case 3: system(str[0]); compress(str[1], str[2]);
draw(activekey); break;
case 4: system(str[0]); expand(str[1], str[2]);
draw(activekey); break;
case 5: help(); draw(activekey); break;
case 6: exit(0); break;
}
mouse_on();
}
//------------------------------------------------------------------------------
// ОСНОВНА ФУНКЦІЯ
//------------------------------------------------------------------------------
void main(int argc, char *argv[])
{
int activekey=5; // Активна кнопка, спочатку help
// Визначення шлячу до зовнішнього файлу
if(argc==1)
PATH="D:\\code\\edu\\";
else
PATH=argv[1];
// Попередні операції
textmode(3);
draw(activekey);
cursor_off();
mouse_on();
// ОСНОВНИЙ ЦИКЛ
for(;;)
{
// Обробка подій миші
if(button_state()==1)
{
int x=x_txt; int y=y_txt;
for(int i=0; i<NK; i++)
if(x>=key[i].x && x<=key[i].x+key[i].l && y==key[i].y)
{
drawKey(&key[activekey], 0);
activekey=i;
drawKey(&key[activekey], 1);
run(activekey);
break;
}
}
// Обробка подій клавіатури
if(kbhit())
{ int c;
switch(c=getch())
{
case 72: drawKey(&key[activekey], 0);
if(activekey>0) activekey--; // UP
else activekey=NK-1;
drawKey(&key[activekey], 1); break;
case 80: drawKey(&key[activekey], 0);
if(activekey<NK-1) activekey++; // DOWN
else activekey=0;
drawKey(&key[activekey], 1); break;
case 13