Міністерство освіти України
Національний університет “Львівська Політехніка”
Кафедра автоматизованих систем управління
Курсова робота
з дисципліни
“Системне програмування та оераційні системи”
Прізвище, ім’я студента
Група КН-22
Тема курсової роботи Середовище об’єднання файлів
Спеціальна частина завдання:
1. Повну реалізацію алгоритму здійснити на мові С.
2. Реалізувати користувацький інтерфейс
3. Середовище функціонування - MS DOS
4. Термін завершення роботи -
Зміст
1. Вступ 3
2. Огляд літератури 5
3. Постановка задачі 6
4. Алгоритм розв’язку задачі 7
5. Програмна реалізація алгоритму 8
6. Інструкція користувачеві 9
7. Контрольні приклади 10
8. Висновки 12
9. Література 13
Додаток. Текст програми 14
Вступ
Світ, у якому ми живемо, прямує до комп’ютерної ери. Якщо багато років тому з винайденням парової машини, електролампи, появою фабрик і заводів були закладені основи індустріального суспільства, то сьогодні, завдяки комп’ютеру, людство створює інформаційне суспільство. Інформаційна революція , яка є ознакою нашого часу, відбувається швидше, ніж відбувалася індустріальна.
З раннього дитинства всі ми беремо участь у процесах обміну інформацією. Запитання, відповіді, прохання і навіть посмішки – все це передавання інформації.
З виникненням писемності інформація стала передаватися не тільки усно або жестами. Вираження думок у письмовій формі відкрило можливість не тільки передавати відомості та повідомлення, а й нагромаджувати знання людей у формі рукописів і рукописних книг і тим самим передавати скарби людської думки від покоління до покоління.
Винахід книгодрукування відкрив можливість видання книжок і широкого розповсюдження шедеврів людської думки. Винахід у ХІХ-на початку ХХ ст. телеграфу, телефону і радіо відкрив перед людьми можливість передавання інформації на будь-яку відстань з швидкістю світла. А винахід телебачення дав нам усім можливість стежити за подіями у світі.
Цілком нові можливості для пошуку та опрацювання інформації відкрив людям винахід у середині ХХ ст. електронних обчислювальних машин – ЕОМ.
Спочатку ЕОМ створювались для автоматизації обчислень. Потім їх навчили записувати та зберігати інформацію на магнітних стрічках, друкувати її на папері і виводити на екран ЕОМ. З подальшим розвитком вони стали використовуватися для створення архівів, підготовки та редагування текстів, виконання креслярських робіт, для автоматизації виробництва і багатьох інших видів людської діяльності.
Існує зворотний вплив інформатики на точні та гуманітарні науки. З допомогою ЕОМ були розв’язані математичні задачі, які ще декілька років тому вважалися недоступними. У фізиці були відкриті явища, про існування яких вчені навіть не догадувалися. У медицині комп’ютер аналізує результати обстежень, допомагає встановити діагноз і підібрати ліки. Отже комп’ютер використовується з великою користю практично у всіх сферах діяльності людини.
Вчені постійно вдосконалюють ЕОМ. Стрімкий розвиток обчислювальної техніки має зворотний вплив на людей: ЕОМ розширює їх можливості, підвищує продуктивність інтелектуальної праці, мінють спосіб життя. Сьогодні все більше і більше фахівців працюють у сферах пов’язаних з опрацюванням інформації та використанням інформаційних технологій.
Огляд літератури
Для розв’язку поставленої задачі необхідним є використання роботи з файлами. Інформацію про роботу з файлами в мові С я почерпнув з довідкового посібника А.І.Касаткіна.
Довідник В.С.Проценка використовувався як джерело інформації про роботу з далекими вказівниками і відеопам’яттю в текстовому режимі.
Для уточнення параметрів стандартних функцій, методів їх використання, пошуку потрібних функцій та як джерело всієї іншої довідкової інформації використовувалась довідкова система середовища С.
Постановка задачі
Дана програма належить до класу системних утиліт і її основною функцією є об’єднання будь-яких файлів.
Процес об’єднання досить зручний для користувача. Користувач вибирає спочатку перший а потім другий файл з списку файлів. При цьому він легко може переходити з каталога в каталог та навіть з одного диску на інший. Також користувач може використовувати клавіші page up та page down для швидкої прокрутки списку, клавішу backspace для переходу в попередній каталог.
Наступним кроком є вибір файлу, в який потрібно записати результат об’єднання. Користувач може вибрати такий файл так само як і попередній, але якщо він бажає створити новий файл, то він може вибрати шлях для результуючого файлу просто перейшовши в потрібну директорію, натиснути escape і ввести ім’я та розширення результуючого файлу з клавіатури.
Після цього програма створює тимчасовий файл, копіює в нього спочатку перший, а потім другй файл (в такому порядку, в якому вони були вибрані), і переіменовує тимчасовий файл в результуючий. Якщо файл з таким іменем вже існує, програма попередить про це і запитає в користувача, чи потрібно переписати файл. Якщо ні, то програма дає змогу вибрати інший результуючий файл, або дати йому інше ім’я.
Користувач може покинути програму, натиснувши в режимі вибору файла Alt+X.
Алгоритм розв’язку задачі
Алгоритм розв’язку виглядає наступним чином. Спочатку користувач вводить імена вхідних та результуючого файлів. Потім створюється тимчасовий файл, в який послідовно копіюється інформація спочатку з першого а потім з другого вхідного файлів. Наступним кроком є переіменування тимчасового файлу в результуючий файл.
Програмна реалізація алгоритму
Програма має назву kurs4.c. Програма має 706 рядки і після компіляції займає 43128 байт.
Програма призначена для об’єднання файлів. Вона має досить зручний інтерфейс, дає можливість переходити з одного диску на інший, послідовно копіює інформацію спочатку з першого а потім з другого файлу в тимчасовий файл, а потім надає цьому файлу відповідне ім’я. Цей метод гарантує, що об’єднання буде успішним в будь-якому випадку, навіть якщо один і той же файл об’єднується сам з собою і результат записується в той самий файл. Але цей метод має також і недоліки. По перше, тимчасовий файл займає місце на диску, чого можна було б уникнути для випадків, коли один з вхідних файлів є також результуючим, а по друге, потребує дещо більше часу, ніж просте дописування другого файлу до першого, у випадку коли перший файл є також результуючим.
До вхідної інформації належать імена та шляхи до файлів, перший та другий файли. До вихідної інформації належить результуючий файл.
Програма нормально працює в середовищі MS DOS, PC DOS, DR DOS та інших DOS та в середовищі Microsoft Windows. Особливих вимог щодо конфігурації комп’ютера немає.
Компіляція та відлагодження програми виконувались в середовищі Borland C або Turbo C.
Інструкція користувачеві
Процес об’єднання досить зручний для користувача. Користувач вибирає спочатку перший а потім другий файл з списку файлів. При цьому він легко може переходити з каталога в каталог та навіть з одного диску на інший. Також користувач може використовувати клавіші page up та page down для швидкої прокрутки списку, клавішу backspace для переходу в попередній каталог.
Наступним кроком є вибір файлу, в який потрібно записати результат об’єднання. Користувач може вибрати такий файл так само як і попередній, але якщо він бажає створити новий файл, то він може вибрати шлях для результуючого файлу просто перейшовши в потрібну директорію, натиснути escape і ввести ім’я та розширення результуючого файлу з клавіатури.
Після цього програма створює тимчасовий файл, копіює в нього спочатку перший, а потім другй файл (в такому порядку, в якому вони були вибрані), і переіменовує тимчасовий файл в результуючий. Якщо файл з таким іменем вже існує, програма попередить про це і запитає в користувача, чи потрібно переписати файл. Якщо ні, то програма дає змогу вибрати інший результуючий файл, або дати йому інше ім’я.
Користувач може покинути програму, натиснувши в режимі вибору файла Alt+X.
Контрольні приклади
Для прикладу об’єднаємо файл autoexec.bat сам з собою і запишемо результат у файл test.res в кореневому каталозі.
Вміст файлу autoexec.bat:
SET BLASTER=A220 I7 D1 H7 P330 T6
SET SBPCI=C:\SBPCI
mode con codepage prepare=((866) C:\WIN98\COMMAND\ega3.cpi)
mode con codepage select=866
keyb ru,,C:\WIN98\COMMAND\keybrd3.sys
Розмір: 189 байт
Виберемо двічі файл autoexec.bat
В кореневому каталозі натиснемо escape і введемо test.res
В результаті об’єднання утворився файл файл test.res в кореневому каталозі.
Вміст файлу test.res:
SET BLASTER=A220 I7 D1 H7 P330 T6
SET SBPCI=C:\SBPCI
mode con codepage prepare=((866) C:\WIN98\COMMAND\ega3.cpi)
mode con codepage select=866
keyb ru,,C:\WIN98\COMMAND\keybrd3.sys
SET BLASTER=A220 I7 D1 H7 P330 T6
SET SBPCI=C:\SBPCI
mode con codepage prepare=((866) C:\WIN98\COMMAND\ega3.cpi)
mode con codepage select=866
keyb ru,,C:\WIN98\COMMAND\keybrd3.sys
Розмір: 378 (179*2) байт
Висновки
Дана програма є абсолютно працездатною і зручною у використанні. Програма є надійно захищена від навмисно неправильного або випадково неправильного вводу даних.
Програма може бути вдосконалена шляхом додання підтримки маніпулятору “миш” та створення графічного інтерфейсу.
Література
Проценко В.С. та ін. Техніка програмування мовою Сі: навчальний посібник./ В.С.Проценко, П.П.Чаленко, А.В.Ставровський. – К.: Либідь, 1993 р.
Касаткін А.І., Вальвачов А.Н. Від Turbo C до Borland C++: довідковий посібник. – Мінск: “Вишейшая школа”, 1992 р.
Довідкова система середовища Borland C++ 3.1
Додаток. Текст програми.
#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>
#include <alloc.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
typedef struct symb
{
unsigned char l,c;
};
symb far *scr=(symb *) MK_FP(0xB800, 0);
typedef struct finf
{
char fname[13];
struct finf *prev;
struct finf *next;
int isdir;
};
struct finf *beg,*cur,*end;
unsigned long numoffiles;
char f1name[13]="",f2name[13]="",f3name[13]="",f1path[129]="",f2path[129]="",f3path[129]="",tmpstr[256];
int nod=setdisk(2),fh1,fh2,noread;
char cdirs[256],timetodie=0;
char *ftmpname = "fctmpXXXXXX";
unsigned char databuff[512];
void clbuf(void)
{
while(kbhit())getch();
}
void cursor_off(void)
{
_AH=0x1;
_CH=0x20;
geninterrupt(0x10);
}
void cursor_on(void)
{
_AH=0x1;
_CH=0x6;
_CL=0x7;
geninterrupt(0x10);
}
void psym(unsigned char x,
unsigned char y,
unsigned char sym,
unsigned char col
)
{
symb far *vm;
vm=scr+x+y*80;
vm->l=sym;
vm->c=col;
}
void cls(void)
{
unsigned char ctr,ctr2;
for(ctr=0;ctr<=80;ctr++)
{
for(ctr2=0;ctr2<=25;ctr2++)
{
psym(ctr,ctr2,'°',0x71);
}
}
}
void destroylist(void)
{
struct finf *cur2;
cur=beg;
if(cur==NULL)return;
cur2=cur->next;
while(cur2!=NULL)
{
cur=cur2;
cur2=cur->next;
free(cur);
}
beg=NULL;
end=NULL;
}
void sortlist(void)
{
struct finf *sel,*cur2;
char ntmp[13],dtmp;
sel=beg->next;
cur=beg->next;
while((cur->next!=NULL)&&(cur!=NULL))
{
cur2=cur->next;
while(cur2!=NULL)
{
if(cur2->fname[0]<sel->fname[0])sel=cur2;
cur2=cur2->next;
}
strcpy(ntmp,sel->fname);
strcpy(sel->fname,cur->fname);
strcpy(cur->fname,ntmp);
dtmp=cur->isdir;
cur->isdir=sel->isdir;
sel->isdir=dtmp;
cur=cur->next;
sel=cur;
}
}
void listdrives(void)
{
struct ffblk fdata;
int cr;
destroylist();
numoffiles=nod;
beg = (finf *) calloc(1,sizeof(finf));
end = beg;
cur = beg;
beg->fname[0]='A';
beg->fname[1]=0;
beg->prev=NULL;
beg->next=NULL;
beg->isdir=666;
for(cr=1;cr<nod;cr++)
{
end = (finf *) calloc(1,sizeof(finf));
cur->next=end;
end->next=NULL;
end->prev=cur;
end->isdir=666;
end->fname[0]='A'+cr;
end->fname[1]=0;
cur=end;
}
}
void listdir(char *dir)
{
struct ffblk fdata;
int done,cr;
destroylist();
numoffiles=1;
chdir(dir);
done = findfirst("*.*",&fdata,63);
beg = (finf *) calloc(1,sizeof(finf));
end = beg;
cur = beg;
strcpy(beg->fname,"..");
beg->prev=NULL;
beg->next=NULL;
while (!done)
{
numoffiles++;
while((*fdata.ff_name=='.') && (!done))
{
if(*(fdata.ff_name+1)=='.')beg->isdir=1;
done = findnext(&fdata);
}
if(done)break;
cur = (finf *) calloc(1,sizeof(finf));
cur->prev=end;
end->next=cur;
cur->next=NULL;
end=cur;
if(fdata.ff_attrib!=FA_DIREC)
{
for(cr=strlen(fdata.ff_name)-1;cr+1;cr--)
{
*(fdata.ff_name+cr)=tolower(*(fdata.ff_name+cr));
}
cur->isdir=0;
}
else
{
cur->isdir=1;
}
strcpy(cur->fname,fdata.ff_name);
done = findnext(&fdata);
}
sortlist();
}
void strprint(unsigned char x1,
unsigned char x2,
unsigned char y,
unsigned char col,
char *strng
)
{
unsigned char ctr;
for(ctr=x1;ctr!=x2+1;ctr++)
{
if(ctr-x1<strlen(strng)) psym(ctr,y,*(strng+ctr-x1),col);
else psym(ctr,y,' ',col);
}
}
void winrect(unsigned char x1,
unsigned char y1,
unsigned char x2,
unsigned char y2,
unsigned char col,
char *title
)
{
unsigned char ctr,ctr2;
char wtitle[79];
strncpy(wtitle,title,x2-x1-1);
wtitle[x2-x1-1]=0;
for(ctr=x2-1;ctr>x1;ctr--)
{
psym(ctr,y1,'Д',col);
psym(ctr,y2,'Д',col);
for(ctr2=y2-1;ctr2>y1;ctr2--)
{
psym(ctr,ctr2,' ',col);
}
}
for(ctr=y2-1;ctr>y1;ctr--)
{
psym(x1,ctr,'і',col);
psym(x2,ctr,'і',col);
}
psym(x1,y1,'Ъ',col);
psym(x2,y1,'ї',col);
psym(x1,y2,'А',col);
psym(x2,y2,'Щ',col);
strprint(div(x2-x1-strlen(wtitle),2).quot+x1+1,div(x2-x1+strlen(wtitle),2).quot+x1,y1,col,wtitle);
}
void winrectd(unsigned char x1,
unsigned char y1,
unsigned char x2,
unsigned char y2,
unsigned char col,
char *title
)
{
unsigned char ctr,ctr2;
char wtitle[79];
strncpy(wtitle,title,x2-x1-1);
wtitle[x2-x1-1]=0;
for(ctr=x2-1;ctr>x1;ctr--)
{
psym(ctr,y1,'Н',col);
psym(ctr,y2,'Н',col);
for(ctr2=y2-1;ctr2>y1;ctr2--)
{
psym(ctr,ctr2,' ',col);
}
}
for(ctr=y2-1;ctr>y1;ctr--)
{
psym(x1,ctr,'є',col);
psym(x2,ctr,'є',col);
}
psym(x1,y1,'Й',col);
psym(x2,y1,'»',col);
psym(x1,y2,'И',col);
psym(x2,y2,'ј',col);
strprint(div(x2-x1-strlen(wtitle),2).quot+x1+1,div(x2-x1+strlen(wtitle),2).quot+x1,y1,col,wtitle);
}
void listdisp(unsigned char x1,
unsigned char y1,
unsigned char x2,
unsigned char y2,
unsigned char cold,
unsigned char colf,
unsigned char cols,
unsigned char nums,
struct finf *frst
)
{
unsigned char ctr;
for(ctr=y1;ctr!=y2+1;ctr++)
{
if(frst!=NULL)
{
if(ctr-y1+1==nums)
{
strprint(x1,x2,ctr,cols,frst->fname);
}
else
{
if(frst->isdir) strprint(x1,x2,ctr,cold,frst->fname);
else strprint(x1,x2,ctr,colf,frst->fname);
}
frst=frst->next;
}
else
{
strprint(x1,x2,ctr,colf,"");
}
}
}
void scrollbar(
unsigned char x,
unsigned char y1,
unsigned char y2,
unsigned char colb,
unsigned char col,
unsigned long max,
unsigned long no
)
{
unsigned char ctr,n;
float rate;
if(max!=1)rate=(no-1)*(y2-y1-2)/(max-1);
else rate=0;
n=(unsigned char) rate;
psym(x,y1,'',colb);
psym(x,y2,'',colb);
for(ctr=y1+1;ctr!=y2;ctr++)
{
psym(x,ctr,'±',col);
}
psym(x,y1+1+n,'ю',colb);
}
void selectfile(
unsigned char x1,
unsigned char y1,
unsigned char x2,
unsigned char y2,
char *dir,
struct finf **ptr,
char *wint
)
{
unsigned int csn,cdf,inp,ctr;
struct finf *curf,*curs;
char tpath[256];
csn=1;
cdf=1;
if(dir[0]=='%')
{
listdrives();
}
else listdir(dir);
curf=curs=beg;
getcurdir(getdisk()+1,tpath);
strcpy(cdirs," :\\");
cdirs[0]=getdisk()+65;
strcat(cdirs,tpath);
if(tpath[0]!=0) strcat(cdirs,"\\");
winrectd(x1,y1,x2,y2,0x1F,wint);
listdisp(x1+2,y1+1,x2-2,y2-1,0x1B,0x1E,0x31,csn-cdf+1,curf);
scrollbar(x2,y1+1,y2-1,0x31,0x13,numoffiles,csn);
inp=getch();
while(inp!=13)
{
if((inp==8) && (dir[0]!='%'))
{
*ptr=beg;
return;
}
if((inp==27) && (dir[0]!='%'))
{
*ptr=NULL;
return;
}
if(inp==0)
{
inp=getch();
if(inp==45)
{
timetodie=1;
destroylist();
return;
}
if(inp==72)
{
if(curs->prev!=NULL)
{
curs=curs->prev;
csn--;
}
if(csn<cdf)
{
cdf--;
curf=curf->prev;
}
listdisp(x1+2,y1+1,x2-2,y2-1,0x1B,0x1E,0x31,csn-cdf+1,curf);
scrollbar(x2,y1+1,y2-1,0x31,0x13,numoffiles,csn);
}
if(inp==80)
{
if(curs->next!=NULL)
{
curs=curs->next;
csn++;
}
if(csn>cdf+y2-y1-2)
{
cdf++;
curf=curf->next;
}
listdisp(x1+2,y1+1,x2-2,y2-1,0x1B,0x1E,0x31,csn-cdf+1,curf);
scrollbar(x2,y1+1,y2-1,0x31,0x13,numoffiles,csn);
}
if(inp==73)
{
for(ctr=y1+1;(curf->prev!=NULL)&&(ctr<y2-1);ctr++)
{
cdf--;
curf=curf->prev;
}
curs=curf;
csn=cdf;
listdisp(x1+2,y1+1,x2-2,y2-1,0x1B,0x1E,0x31,csn-cdf+1,curf);
scrollbar(x2,y1+1,y2-1,0x31,0x13,numoffiles,csn);
}
if(inp==81)
{
for(ctr=y1+1;(curf->next!=NULL) && (ctr<y2-1);ctr++)
{
cdf++;
curf=curf->next;
}
curs=curf;
csn=cdf;
listdisp(x1+2,y1+1,x2-2,y2-1,0x1B,0x1E,0x31,csn-cdf+1,curf);
scrollbar(x2,y1+1,y2-1,0x31,0x13,numoffiles,csn);
}
}
inp=getch();
}
*ptr=curs;
}
void stats (void)
{
winrect(1,1,78,7,0x1F,"");
strprint(4,11,3,0x1B,"” ©« #1:");
strprint(4,11,4,0x1B,"” ©« #2:");
strprint(4,11,5,0x1B,"” ©« #3:");
strprint(13,61,3,0x0B,f1path);
strprint(13,61,4,0x0B,f2path);
strprint(13,61,5,0x0B,f3path);
strprint(63,75,3,0x0E,f1name);
strprint(63,75,4,0x0E,f2name);
strprint(63,75,5,0x0E,f3name);
}
int sfile(char *fnameres, char *pathres)
{
struct finf *pstfile=NULL;
char fname[13];
selectfile(2,9,38,23,"",&pstfile,cdirs);
if(timetodie)return 0;
while(((pstfile->isdir)&&(pstfile!=NULL))||(pstfile->fname[0]=='.'))
{
strcpy(fname,pstfile->fname);
if((pstfile->fname[0]=='.')&&(pstfile->isdir==0))
{
selectfile(2,9,38,23,"%",&pstfile,cdirs);
if(timetodie)return 0;
if(pstfile->isdir==666)
{
setdisk(pstfile->fname[0]-'A');
}
}else
{
selectfile(2,9,38,23,fname,&pstfile,cdirs);
if(timetodie)return 0;
}
}
strcpy(pathres,cdirs);
if(pstfile==NULL) return -1;
strcpy(fnameres,pstfile->fname);
destroylist();
return 0;
}
void main(void) // The Beginning of the End
{
unsigned char f,c;
cursor_off();
cls();
winrectd(1,3,78,21,0x0F," Љгаб®ў а®Ў®в ");
strprint(6,77,5,0x0E,"Љгаб®ў а®Ў®в '‘ҐаҐ¤®ўЁйҐ ®Ў'ч¤ п ¤ў®е д ©«уў' § ¤ЁбжЁЇ«iЁ ‘ЏiЋ‘");
strprint(7,77,6,0x0E,"бв㤥⠣агЇЁ ЉЌ-21 Њ еi ЊЁЄ®«Ё, тЉЌт’, тт-© Єгаб (IV-© ᥬҐбва)");
strprint(3,77,9,0x0E," „«п в®Ј®, й®Ў ®'Ўч¤ вЁ ¤ў д ©« Ї®вауЎ® бЇ®з вЄг ўЁЎа вЁ ЇҐаиЁ© д ©«");
strprint(3,77,10,0x0E,"у§ бЇЁбЄг д ©«уў, Ї®ву¬ ¤агЈЁ© д ©«, Ї®ву¬ Ў® ўЁЎа вЁ д ©«, ў пЄЁ© Ўг¤Ґ");
strprint(3,77,11,0x0E,"§ Їуб Ё© १г«мв в ®Ў'ч¤ п. Њ®¦ в Є®¦ ўЁЎа вЁ и«пе ¤® १г«мвгоз®Ј®");
strprint(3,77,12,0x0E,"д ©«г, вЁбгвЁ escape у ўўҐбвЁ у¬'п ¤«п жм®Ј® д ©«г. ‚ в Є®¬г ўЁЇ ¤Єг");
strprint(3,77,13,0x0E,"пЄй® д ©« § в ЄЁ¬ 󬥥¬ ў ўЁЎа у© ¤у४в®аух Ґ убгч, в® в ЄЁ© д ©«");
strprint(3,77,14,0x0E,"Ўг¤Ґ б⢮२©. ” ©«Ё Ўг¤гвм ®Ў'ч¤ у ў в Є®¬г Ї®ап¤Єг, ў пЄ®¬г ў®Ё Ўг«Ё");
strprint(3,77,15,0x0E,"ўЁЎа у. ЏаЁ ўЁЎ®ау д ©«уў ў бЇЁбЄг ¬®¦ Є®аЁбвгў вЁбм Є« ўуи ¬Ё page up,");
strprint(3,77,16,0x0E,"page down в backspace.");
strprint(3,77,19,0x0E,"„«п ўЁе®¤г § Їа®Ја ¬Ё Їу¤ з б ўЁЎ®аг д ©«уў Ї®вауЎ® вЁбгвЁ Alt+X.");
clbuf();
getch();
firstbreath: