Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii.doc
Скачиваний:
46
Добавлен:
31.03.2015
Размер:
773.63 Кб
Скачать

Лекции 21-22: Основные задачи обработки файлов.

1. Общая характеристика задач обработки файлов.

2. Создание файлов.

3. Анализ текстовых файлов.

4. Сортировка текстовых файлов.

5. Коррекция текстовых файлов.

6. Поиск и выборка данных из файлов.

7. Печать текстовых файлов.

1. Общая характеристика задач обработки файлов.

Файлы - одна из наиболее используемых структур данных в системах автоматизации управления (офисных системах), проектирования и моделирования. В этих системах файлы часто являются не только средством долговременного хранения данных, но и средством связи между различными процессами обработки данных (связь по данным). Файлы, объединенные по функциональному или иному принципу, составляют интегрированную базу данных, информация которой может быть доступна одной или нескольким системам обработки данных. Базы данных и связанные с ними проблемы обычно изучаются в отдельном курсе программистского цикла.

Практика создания и использования систем обработки файлов данных накопила в настоящее время солидный опыт и определила некоторые базисные задачи для таких систем, а также эффективные методы их алгоритмизации. Это достаточно обширная область, выходящая за рамки основ программирования. Поэтому в данном курсе мы остановимся лишь на некоторых простейших примерах таких задач, которые можно рассматривать лишь как введение в типовые задачи обработки файлов данных. К числу таких задач мы отнесли:

 создание файла, т.е. ввод данных в новый или в существующий файл;

 анализ файла, т.е. просмотр (чтение) всего содержимого файла и вычисление некоторых интегральных характеристик или показателей этого содержимого;

 сортировка файла, предполагающая упорядочение записей файла по заданному логическому критерию, зависящему от содержания записей;

 коррекция файла, т.е. изменение содержимого файла либо путем обновления записей, либо коррекции по некоторым глобальным критериям (например, удаление "лишних" записей);

 поиск и выборка данных по некоторым логическим критериям содержимого записей файла;

 печать файла, т.е. вывод файла на принтер или на экран в заданном формате размещения информации из записей файла;

2. Создание файла.

Создание файла данных - важнейшая процедура, с которой обычно начинается цикл обработки данных. Она предполагает добавление исходных данных в пустой файл или в уже созданный ранее файл. Исходные данные могут вводиться с различных носителей (в том числе с клавиатуры). Типичной проблемой при вводе исходных данных является контроль возможных ошибок (как синтаксических, таких как соответствие формату или шаблону, так и семантических, связанных со значениями данных). Турбо Паскаль предоставляет для текстовых и типизированных файлов простые средства, как создания нового файла, так и добавления записей в уже существующий файл, а также проверки существования файла или возможности открытия нового файла на указанном носителе.

Следующий пример программы иллюстрирует простой алгоритм создания типизированного файла с некоторыми процедурами контроля. Он является модификацией рассмотренного ранее примера программы работы с массивом записей о группе студентов (см. Лекцию 16), в которой массив заменен файлом записей.

program create_file; {Создание файла данных о группе студентов}

uses CRT;

type stud =record num:byte;name:string[16];average:real end;

gr_st=file of stud;{типизированный файл записей}

var gr:gr_st{файл группы студентов}; st:stud{запись о студенте};

nm:string{имя исходного файла}; s:char{признак Y/N};

numb:integer{число записей в файле nm};

BEGIN clrscr; repeat write('Имя файла: ');readln(nm);

if nm='' then halt;assign(gr,nm);s:='Y';

{$I-}reset(gr);{$I+} if IOResult<>0 then

begin write('Открыть новый файл ', nm, '?(Y/N)');

readln(s); if upcase(s)='Y' then

begin {$I-}rewrite(gr);{$I+} if IOResult<>0 then

begin writeln('Диск недоступен!');nm:= '' end;

end else nm:='';

end until nm<>'';numb:=0;if upcase(s)='Y' then

begin seek(gr,filesize(gr));numb:=filesize(gr) end;

writeln('Всего записей в файле:',numb, '. Введите очередную запись:');

with st do repeat repeat writeln('Фамилия,инициалы ','Cредний балл');

readln(name,average);if(average<2)or(average>5) then

writeln('Ошибка! Повторите ввод последней записи');

until(average>=2)and(average<=5);inc(numb);num:=numb; write(gr,st);write('Ввод следующей записи?(y/n)');readln(s);

until upcase(s)<>'Y';close(gr);if numb=0 then erase(gr);

{Конец цикла записи}writeln('Всего записей в файле ',nm,' ',numb);

END {create_file}.

3. Анализ текстовых файлов.

Одной из типичных задач анализа файла является вычисление объёма текстового файла. При этом, в понятие объёма может вкладываться различный смысл: от общего числа символов в файле, до более утонченных оценок, например учитывающих только информационные символы (без управляющих символов), специальным образом учитывающим пробелы, отдельно учитывающим русские и латинские символы, текст и формулы и др. Ниже приведён пример одной из программ вычисления объема текстового файла в авторских листах:

program volume;

{ Расчет объема файла, где цепочки пробелов учитываются как один символ}

uses CRT, DOS;

const pg=#12;

var total:pathstr;str:dirstr;fn:namestr;fr:extstr;

ft:text;alfa,beta:Boolean;

j,page:byte;a,symb:longint;author:real;

procedure setdisc;

var c:string;

begin writeln(' Установите дискету с файлом ', fn,' и нажмите enter');

readln(c);{$I-}reset(ft);{$I+}

if IOResult<>0 then begin writeln(' Файл ',fn,' не найден!');readln;halt end;

end{setdisc};

procedure checknm;

var i:byte;digit:set of '0'..'9';

begin if str <>'' then

begin for i:=1 to length(str) do if not (str[i] <>' ') then

if (str[i]='-') and (str[i+1] in digit) then str:='';

alfa:=false;

end;

end{checknm};

BEGIN page:=1;symb:=0;a:=0;alfa:=false;beta:=false;

writeln(' Введите полное имя анализируемого файла:');

readln(total);assign(ft,total);fsplit(total,str,fn,fr);

{$I-}reset(ft);{$I+} if IOResult<>0 then

begin for j:=(length(total)-length(fn)-length(fr)) downto 1 do

if total[j] in ['A'..'Z','a'..'z'] then

if not (total[j] in ['a','A','b','B']) then

begin writeln(' Файл ',fn,' не найден');readln;halt end

else

begin setdisc;break end;

end;

repeat readln(ft,str);if str<>'' then

begin symb:=symb+length(str);for j:=1 to length(str) do

begin if alfa then checknm;

if str[j]=pg then begin page:=page+1;alfa:=true end;

if not (str[j] in [pg,' ']) and (not alfa) then inc(a);

if str[j]=' ' then beta:=true;

if beta and not (str[j] in [pg,' ']) then

begin inc(a);beta:=false end;

end;

end;

until eof(ft);

author:=a/40000; clrscr;gotoXY(10,10);

write(' ОБЪЕМ ТЕКСТА ',fn);gotoXY(10,11);

write(' Страниц: ',page);gotoXY(10,12);

write(' Всего символов в тексте: ',symb);gotoXY(10,13);

write(' Объем в авторских листах: ',author:2:3);

gotoXY(10,14);for j:=20 to 80 do write('_');writeln; readln;

END {volume}.

4. Сортировка текстовых файлов.

Сортировка файлов - весьма распространенная процедура, направленная на повышение эффективности многих важных процессов обработки файлов. По сути, сортировка - ключевая процедура для всего цикла обработки. Методы сортировки и их алгоритмизация достаточно хорошо изучены и описаны. Не имея возможности сколько-нибудь детально осветить здесь эту проблему, остановимся лишь на одном распространенном методе сортировки - методе "трёх лент" (названном ещё в старые и добрые времена, когда ленты были распространенным видом внешних носителей).

Сортировка файла принципиально отличается от сортировки массива данных тем, что файл может иметь любой размер. Поэтому нет гарантии того, что весь файл может быть одновременно помещен в оперативную память. Следовательно, сортировка файла должна использовать дополнительные файлы для хранения промежуточной информации. Метод "трёх лент" использует для этих целей два дополнительных файла, а основной идеей сортировки является чередование фаз "разделения" и "слияния" файлов до получения полностью отсортированного файла. Поясним эту идею более подробно.

Пусть требуется сортировать по возрастанию записей файл F, состоящий из последовательности записей-чисел R1,R2,...Rn, где n - число записей. Чтобы сформулировать эффективный критерий "разделения" файла, введём понятие:

Отрезок монотонности файла - это последовательность записей Ri,Ri+1, Ri+2, ... Ri+m файла, удовлетворяющая условию:

Ri <= Ri+1<= Ri+2 <= ..Ri+m и Ri-1>Ri, если i>1; Ri+m>Ri+m+1, если i+m<n.

Другими словами, отрезок монотонности - это последовательность упорядоченных записей файла, к которой не может быть добавлена ни одна запись слева или справа без нарушения свойства монотонности (этот отрезок может состоять, в частности, и из одной единственной записи). В файле может быть несколько непересекающихся отрезков монотонности Q1,Q2,...Qt, осуществляющих разбиение файла.

Для "разделения" заданного файла F на два файла F1 и F2 используем следующий критерий: при последовательном просмотре файла F отрезки монотонности с нечётными номерами Q1,Q3,... записываются в F1, а с чётными номерами Q2,Q4,... - в F2.

"Слиянием" файлов F1 и F2 в файл F назовем процесс записи в F следующей последовательности компонентов F1 и F2:

1) минимальный из первых компонентов F1 и F2;

2) минимальный из оставшегося незаписанным компонента предыдущего шага (сохранённого в буфере) и очередного прочитанного компонента из того файла, компонента которого была записана на предыдущем шаге.

3) если буфер пуст, то записи подлежит каждый прочитанный компонент в оставшейся части файла F1 или F2.

Каждый цикл "разделение-слияние" будет уменьшать количество отрезков монотонности в два раза, так как каждая пара отрезков (отрезок из F1 и отрезок из F2) будет слита в один отрезок в F. Таким образом, процесс сходится к состоянию, содержащему один отрезок монотонности (т.е. к отсортированному файлу F) не более чем за log2 (t) циклов "разделение-слияние".

Ниже приводится процедура сортировки текстового файла, реализующая описанный выше метод "трёх лент", оформленная в виде модуля Турбо Паскаля s_text и пример её использования - сортировка текстового файла по страницам:

UNIT s_text; {Модуль-процедура sort_file}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]