Міністерство освіти України
Національний університет “Львівська політехніка”
Кафедра автоматизованих систем управління
Курсова робота
з дисципліни
“Системне програмування”
на тему
ПОШУК ФАЙЛІВ ЗА ЗАДАНИМИ АТРИБУТАМИ
Міністерство освіти України
Національний університет “Львівська політехніка”
Кафедра автоматизованих систем управління
Завдання на курсову роботу
з дисципліни
“Системне програмування”
Прізвище, ім’я студента Янчак Олег
Група КН - 22
Тема курсової роботи Пошук файлів за заданими
атрибутами
Спеціальна частина завдання:
Ознайомитися з організацією файлової системи MS DOS.
Реалізувати пошук файла в межах заданого каталога, а також вкладених каталогів.
Пошук здійснювати за іменем, розширенням і датою створення файла.
Завдання видано .
Керівник (підпис)
Студент (підпис)
Зміст
Стор.
Вступ
4
1. Огляд літератури.
5
2. Постановка задачі.
6
3. Алгоритм розв’язку задачі.
8
4. Програмні реалізації алгоритму.
11
4.2. Опис програмного комплексу на мові Turbo С.
12
5. Інструкція користувачеві.
13
6. Контрольні приклади та аналіз їх реалізацій.
14
Висновки.
15
Список використаної літератури.
16
Додатки
18
Пояснювальна записка
Вступ.
Тема моєї курсової роботи – „ Пошук файлів за заданими атрибутами.”
Метою даної курсової роботи є реалізація програми яка б могла здійснювати пошук файлу на жорсткому диску комп’ютера за заданим іменем, розширенням, розміром та датою створення файла. Також даний програмний продукт повинен передбачати пошук файлу за одним із вище вказаних атрибутів, при чому повинно бути передбачено задання неповної назви файлу, тобто в разі невідомого імені чи розширення потрібно ввести символ “*”, а якщо невідомим буде якийсь один символ то замість нього потрібно буде вести “?”. Навіть при таких обставинах буде здійснюватись пошук файлів оскільки функції пошуку (findfirst, findnext) передбачають такі шаблони. Дана програма може мати застосування в операційній системі DOS, оскільки в ній дуже важко знайти необхідний файл, не знаючи шляху до нього. Програма повинна знаходити і виводити на екран усі файли не залежно від їх типу.
1. Огляд літератури.
Я провів огляд ряду літератури, ознайомився з організацією файлової системи MS DOS. Ознайомився з функціями бібліотеки <dir.h>, <dos.h> мови програмування Turbo C. В модулях багато функцій та процедур для роботи із файлами, а зокрема за часом їх створення, розміром, розширенням, тобто завдяки цьому модулю можна отримати повний доступ до файла та його атрибутів.
При записі даного програмного продукту на мові програмування Turbo C використовуються процедури пошуку FindFirst та FindNext.
Прототипи функцій fіndfіrst() і fіndnext() містяться у файлі dіr.h. Однак необхідно включити також файл dos.h, що містить макроси, які використовуються як значення параметра attrіb. Ці функції не визначені стандартом ANSІ С.
Функція fіndfіrst() шукає перше ім'я файлу, що відповідає зразку пошуку, на який указує параметр fname. Ім'я файлу може містити в собі диск і шлях. Також ім'я файлу може містити в собі шаблони пошуку * і ?. При перебуванні придатного файлу структура, на яку вказує ptr, заповнюється інформацією про цей файл.
Структура ffblk визначена для DOS і Wіndows 3.1 у такий спосіб:
struct ffblk {
char ff_reserved[21]; /* зарезервовано */
char ff attrіb; /* атрибути файлу */
unsіgned ff ftіme; /* час створення */
unsіgned ff fdate; /* дата створення */
long ff_fsіze; /* розмір у байтах */
char ff name[13]; /* ім'я файлу */ };
Структура ffblk визначена для Wіndows 95/NT у такий спосіб:
struct .ffblk {
long ff_reserved; / * зарезервовано */
long ff_fsіze; / *розмір у байтах */
unsіgned long ff_attrіb; /* атрибути файлу */
unsіgned short ff_ftіme; / *час створення */
unsіgned short ff fdate; / *дата створення */
char ff name[256]; / *ім'я файлу */ };
Параметр attrіb визначає тип файлів, які необхідно знайти за допомогою функції fіndfіrst(). Якщо attrіb має значення 0, то припустимими є усі файли, що підходять під шаблон пошуку. Для того, щоб забезпечити більш ефективний пошук, параметр attrіb може приймати одне зі значень, обумовлених наступними макросами:
Макрос Значення
FA_RDONLY Файл тільки для читання
FA_HІDDEN Схований файл
FA_SYSTEM Системний файл
FA_LABEL Мітка тому
FA_DІREC Підкаталог
FA_ARCH Архівний файл
Функція fіndnext() продовжує пошук, початий функцією fіndfіrst().
Обидві функції fіndfіrst() і fіndnext() у випадку успіху повертають 0. У випадку невдачі повертається -1, а перемінна errno установлюється рівної ENOENT (ім'я файлу не знайдене). Переменнaя_doserror установлюється рівної або ENMFІLE (немає більше файлів у каталозі), або ENOENT.
Оскільки у структурі ffblk розмір і дата створення файлу числові типи відповідно longint та shortint а числа при введенні будуть розпізнаватися як текстовий рядок (string) то для їх перетворення у числовий тип необхідно буде викликати заголовний файл <string.h> для можливості виклику функції atoi.
Int atoi(char *str) – перетворює рядок str в десяткове ціле, а якщо число перевищує діапазон int то повертає два молодші байти. Якщо перетворення неможливе – повертає 0.
Long atol(char *str) – перетворює рядок в довге десяткове ціле.
З цього ж заголовного файлу використовуватиметься функція strcat для того щоб скласти шлях пошуку файла, тобто назва файлу чи інший його атрибут буде вводитися окремо від диску на якому потрібно шукати.
Car *strcat(char *sp, char *si) в цюму випадку рядок si дописується до рядка sp. Результатом об’єднання буде sp/
Приклад
Наступна програма виводить усі файли з розширенням *.с поточного робочого каталогу, а також їхні розміри:
#іnclude <stdіo.h>
#іnclude <dos.h>
#іnclude <dіr.h>
іnt maіn(voіd) {
struct ffblk f;
regіster іnt done;
done = fіndfіrst("*.c", &f, 0);
whіle(!done) {
prіntf("%s %ld\n", f.ff_name, f.ff_fsіze);
done = fіndnext (&f) ;
}return 0;
}
Дійсно дана програма знаходить файли лише в робочому каталозі. Для того щоб програма здійснювала пошук по усіх вкладених директоріях (папках) необхідно використати рекурсивну функцію. Рекурсивною називається функція, яка викликає сама себе. Проте особливо важливий момент полягає в тому щоб вийти з неї таким чином потрібно ставити умову виходу, оскільки функція яка викликає сама себе може робити це безкінечно.
Приклад
#include <stdio.h>
void up_and_down (int);
int main (void)
{up_and_down(1);
return 0;}
void up_and_down (int n)
{printf (“Рівень %d\n”, n) /*оператор виведення #1*/
if (n<4) up_and_down (n+1);
printf(“Рівень %d\n”, n) }/*оператор виведення #2*/
результат роботи цієї програми:
Рівень 1
Рівень 2
Рівень 3
Рівень 4
Рівень 4
Рівень 3
Рівень 2
Рівень 1
Принцип роботи цієї рекурсивної програми такий. Спочатку функція main() викликає функцію up_and_down з параметром 1, в результаті n приймає значення 1і оператор друку #1 виводить рядок “Рівень 1”. Далі поскільки n<4 функція up_and_down (рівня 1) викликає функцію up_and_down (рівня 2) з аргументом n+1 і оператор друку #1 “Рівень 2”. Аналогічно з 3 і 4 рівнем.
Коли n буде рівним 4 умова if дасть негативний результат і функція up_and_down більше не викликається. Замість цього виклик рівня 4 переходить на оператор виведення #2 і виводиться рядок “Рівень 4”. Виклик рівня 4 завершується оператором return і керування передається назад викликавшій його функції –рівню3.
Останнім оператором я кий виконався у 3-му рівні був оператор if тож робота продовжується з наступного – оператор виведення #2, буде виведений рядок “Рівень 3” і т. д.
2. Постановка задачі.
Головна задача даної програми – здійснення пошуку файлу чи файлів за заданими атрибутами. В даній програмі будуть використовуватися дві основні функції Findfirst() та Findnext() з заголовного файла <dir.h> також будуть використовуватися функції переведення з формату string в числовий формат і найголовніше потрібно буде використати рекурсивну функцію для перегляду усіх вкладених директорій (папок), приклад і принцип роботи рекурсивної функції описаний вище. При програмній реалізації даної задачі, як результат ми повинні отримати символьний рядок, який буде містити повний шлях до заданого файлу, а також ім’я цього файлу. Якщо файлів багато, то в такому разі результатом повинен бути список символьних рядків. При чому виведення повинно зупинятись при заповненні кожної відео сторінки і програма повинна очікувати на натискання будь-якої клавіші.
Розв’язок буде існувати в тому разі, якщо буде коректно задана вхідна інформація, тобто, якщо невідомим є розширення файла чи його назва, то потрібно просто поставити “ * ”, при невідомому символі необхідно ввести “ ? ”. Вказувати назву диску потрібно у такому вигляді – “ C:\ ”. В разі неправильного введення не буде знайдено жодного файлу.
3. Алгоритм розв’язку задачі.
При запуску програми потрібно вибрати з меню пошуку атрибут за яким треба шукати файл(ли). Передбачене введення назви файла, розміру чи дати створення. Звичайно можна здійснювати пошук зад ним із атрибутів.назва файлу може бути неповною. Потім вказуємо назву диску на якому шукаємо (тут обов’язково вказати назву).
Дата створення файлу вводиться у форматі Рік.Місяць.День.
Розмір файлу вводиться в байтах.
Назва диску повинна бути вказана у виді – “ C:\ ”.
4. Програмна реалізація алгоритму.
Загальна характеристика програми:
Ім’я програми – search
Назва файла – finddos.срр
Мова програмування – Turbo С
Об’єм програми – текстових рядків або байт –162 текстових рядків або
4903 байти.
Призначення програми:
Програма призначена для пошуку файлів на жорсткому диску комп’ютера.
Вхідна інформація:
Вхідні дані вводяться з клавіатури, при чому спочатку потрібно вибрати в меню тип(пи) даних за яким(ми) буде виконуватися пошук. Кількість символів на назву файла – 12, тобто 8 – ім’я, 1 – “.”, 3 – розширення. Розмір файла вводиться в байтах для більшої конкретизації пошуку. Дата створення файла вводиться в форматі Рік.Місяць.День. Назву диска потрібно вказувати у вигляді “c:\”.
Вихідна інформація:
Виводиться у вигляді символьного рядка (рядків). В разі якщо виводиться велика кількість файлів проводиться запинка з очікуванням наскання клавіші після кожного заповнення відеосторінки.
5. Інструкція користувачеві.
Запустити exe-файл програми.
Ввести назву файла.
Ввести розмір даного файла.
Ввести дату створення файла.
Ввести назву диску на якому шукаємо.
Подивитись результати на екрані .
Для виходу, або для просування списку знайдених файлів натиснути будь-яку клавішу.
6. Контрольні приклади та аналіз їх реалізації.
Для перевірки працездатності програми проведемо експеримент.
Приклад №1
В цьому приклді будемо шукати за даною назвою і розширенням
Search with ?
< * > File name: cdc.pas
< > File size :
< > File date :
OK
Натиснуши OK вказуємо диск: D:\
Отримуємо результат у вигляді: D:\BC5\CDC.PAS
Приклад №2
Тепер вкажемо лише розмір файла
Search with ?
< > File name:
< * > File size : 19840
< > File date :
OK
Результат : D:\KURSAK\C\NEW\FINDFILE.EXE
Приклад №3
Вказавши дату створення
Search with ?
< > File name:
< > File size :
< * > File date : 2003.04.23
OK
Отримаємо такий результат : D:\KURSAK\C\NEW\FINDFILE.EXE
Висновки.
Отже програма працює коректно. Як видно з результатів здійснюється пошук за всіма атрибутами файлу. Перевіривши результати можна переконатись у вірності виконання пошуку, бо у двох останніх прикладах ми шукали один і той самий файл, але за різними атрибутами.
Даний програмний продукт був опротестований на таких операційних системах, як MS DOS 5.0/6.0/6.2 та Windows 95/98/Me/Xp. В усіх цих операційних системах працювала правильно.
Список використаної літератури.
Громов Ю.Ю.,Татаренко С.И. Программирование на языке СИ: Учебное пособие.. -Тамбов,1995.- 169 с.
Блох А.Ш, Граф-схемы и алгоритмы. - Минск: Высш. шк., 1987.
Вирт Н, Алгоритмы и структуры данных. - М.: Мир, 1989.
Языки программирования Ада, Си, Паскаль: сравнение и оценки. -М.: Радио и связь, 1989.
Башкин А.В., Дубнер П.Н. Работа в Турбо СИ. НИВФ ЮКИС, 1991.
Болски М.И. Язык программирование Си: Справочник. - М.: Радио и связь, 1988.
Керниган Б., Ритчи Д. Язык программирования Си. - М.: Финансы и статистика, 1992.
Страуструп Б. Язык программирования Си++. - М.: Радио и связь, 1991.
Проценко В.С., Чаленко Б.И., Старовський А-Б. Техніка програмування мовою Сі. - К.: Либідь, 1993.
Уэйт М., Прата С., Мартин Д. Язык Си: руководство для начинающих. - М.: Мир, 1988
Додатки.
Додаток №1
Текст програми на мові Turbo C.
#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>
#include <stdlib.h>
char *FileName;
long iFileSize;
int iFileDate;
long R=0;
unsigned int c;
char Ar1[3];
void Search(char *Dir)
{
int L, l2;
struct ffblk ffblk, Fs;
int derror;
char *DirS;
/*--------------------------------------------- FindFile ------------------------------------------*/
int fDosError;
char *fDir;
fDir[0]=0;
strcat(fDir,Dir);
strcat(fDir,FileName);
fDosError = findfirst(fDir,&Fs,0);
while (!fDosError)
{ if (Ar1[1]==1) if (Fs.ff_fsize!=iFileSize) goto skip2;
if (Ar1[2]==1) if (Fs.ff_fdate!=iFileDate) goto skip2;
c=c+1;
R=R+1;
if (c==24){c=0;textcolor(4);cprintf("Press any key to continue\r");
getch();
textcolor(14);
cprintf(" \r");}
printf(" ");
printf("%s",Dir);printf("%s",Fs.ff_name);
printf("\n");
skip2: fDosError = findnext(&Fs);
}
/*------------------------------------- End FindFile --------------------------------------------*/
DirS[0]=0;
strcat(DirS,Dir);
l2=strlen(DirS);
DirS[l2]='*';
DirS[l2+1]='.';
DirS[l2+2]='*';
DirS[l2+3]=0;
derror = findfirst(DirS,&ffblk,16);
while (!derror)
{
int atr=ffblk.ff_attrib & 16;
int st1,st2;
st1=strcmp(ffblk.ff_name,".");
st2=strcmp(ffblk.ff_name,"..");
if (st1 != 0 && st2 != 0 && atr==16)
{
strcat(Dir,ffblk.ff_name);
char *p2="\\";
strcat(Dir,p2);
L=strlen(ffblk.ff_name)+1;
Search(Dir);
Dir[strlen(Dir)-L]=0;
}
derror = findnext(&ffblk);
}
}
void grp(int pozc)
{
textcolor(14);
textbackground(0);
gotoxy(4,2);cprintf(" < > File Name: ");
if (Ar1[0]==1) {gotoxy(6,2);cprintf("*");}else {gotoxy(6,2);cprintf(" ");}
gotoxy(4,3);cprintf(" < > File Size: ");
if (Ar1[1]==1) {gotoxy(6,3);cprintf("*");}else {gotoxy(6,3);cprintf(" ");}
gotoxy(4,4);cprintf(" < > File Date: ");
if (Ar1[2]==1) {gotoxy(6,4);cprintf("*");}else {gotoxy(6,4);cprintf(" ");}
textbackground(1);
textcolor(15);
gotoxy(7,5);cprintf(" OK ");
textcolor(14);
switch (pozc)
{
case 1:{textbackground(1);gotoxy(4,2);cprintf(" < > File Name: ");
if (Ar1[0]==1) {gotoxy(6,2);cprintf("*");gotoxy(wherex()-1,2);}
else {gotoxy(6,2);cprintf(" ");gotoxy(wherex()-1,2);}break;}
case 2:{textbackground(1);gotoxy(4,3);cprintf(" < > File Size: ");
if (Ar1[1]==1) {gotoxy(6,3);cprintf("*");gotoxy(wherex()-1,3);}
else {gotoxy(6,3);cprintf(" ");gotoxy(wherex()-1,3);}break;}
case 3:{textbackground(1);gotoxy(4,4);cprintf(" < > File Date: ");
if (Ar1[2]==1) {gotoxy(6,4);cprintf("*");gotoxy(wherex()-1,4);}
else {gotoxy(6,4);cprintf(" ");gotoxy(wherex()-1,4);}break;}
case 4:{textbackground(4);textcolor(14);gotoxy(7,5);cprintf(" OK ");break;}
}
return;
}
void main (void)
{
char *Path;
char *_FileName;
char *FileSize;
char *FileDate;
c=0;
FileName[0]=0;
_FileName[0]=0;
textcolor(14);
textbackground(0);
clrscr();
/*--------------------------------------------------------------------------------------------------*/
Ar1[0]=0;Ar1[1]=0;Ar1[2]=0;
int poz=1;
textcolor(10);
cprintf(" Search With ?\n\r");
grp(1);
char klav;
while (klav!=27)
{
grp(poz);
klav=getch();
if (klav==0) klav=getch();
{if (klav==80) if (poz!=4) poz=poz+1; else poz=1;
if (klav==72) if (poz!=1) poz=poz-1; else poz=4;
}
if (klav==13)
{
grp(0);gotoxy(23,poz+1);
switch(poz) {case 1:printf(" "); gotoxy(24,poz+1);gets(_FileName);
if (strlen(_FileName)!=0)Ar1[0]=1;else Ar1[0]=0;break;
case 2:printf(" ");
gotoxy(24,poz+1);gets(FileSize);
if (strlen(FileSize)!=0)Ar1[1]=1;else Ar1[1]=0;break;
/* Format file date year.month.day [yy.mm.dd] */
case 3:printf(" "); gotoxy(24,poz+1);gets(FileDate);
if (strlen(FileDate)!=0)Ar1[2]=1;else Ar1[2]=0;break;
case 4:goto skip1;}
};
}
if (klav==27) goto h_end;
skip1:
if (Ar1[1]==1) iFileSize=atol(FileSize);
if (Ar1[2]==1) {
char *dops;
dops[0]=FileDate[0];dops[1]=FileDate[1];dops[2]=0;
iFileDate=(atoi(dops)+20)*(2*2*2*2*2*2*2*2*2);
dops[0]=FileDate[3];dops[1]=FileDate[4];dops[2]=0;
iFileDate=iFileDate+atoi(dops)*(2*2*2*2*2);
dops[0]=FileDate[6];dops[1]=FileDate[7];dops[2]=0;
iFileDate=iFileDate+atoi(dops);
}
if (strlen(_FileName)==0 && Ar1[1]==0 && Ar1[2]==0) goto h_end;
if (strlen(_FileName)==0) _FileName="*.*";
FileName=_FileName;
/*--------------------------------------------------------------------------------------------------*/
textcolor(14);
textbackground(0);
clrscr();
printf("Enter Path: ");
gets(Path);
printf(" File List:\n");
Search(Path);
printf(" %d",R);
printf(" File(s)\n");
printf(" Push Any Key\n");
getch();
/*--------------------------------------------------------------------------------------------------*/
h_end:
textcolor(7);
textbackground(0);
clrscr();
return;
}