28641

Основные задачи обработки файлов

Лекция

Информатика, кибернетика и программирование

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

Русский

2013-08-20

100 KB

7 чел.

Лекции 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}

              

     interface

               procedure sort_file(var f:text;r:Boolean);

     implementation

     procedure sort_file; {Сортировка текстового файла}

     {r=false - по убыванию, true - по возрастанию}

     var f1,f2:text;b,b1,b2:string;i,i1,i2,p:Boolean;k:integer;

         function more_less(x,y:string;ord:Boolean):Boolean;

            begin if ord then more_less:=(x<y)

                                else more_less:=(x>=y)

            end { more_less};

     procedure read_str(var t:text;var buf:string;var big:Boolean);

            var s:string;

            begin s:=buf;readln(t,buf);if (buf=s) then big:=false

                                                                    else big:=more_less(buf,s,r);

            end { read_str};

    procedure write_str(var t:text;buf:string;var int:Boolean);

         begin if not int then writeln(f,buf);if eof(t) then int:=true

         end { write_str};

     BEGIN {sort_file} assign(f1,'F1');assign(f2,'F2');

           repeat {разделение на 2 файла}reset(f);rewrite(f1);rewrite(f2);

             k:=1;readln(f,b);writeln(f1,b);while not eof(f) do

             begin read_str(f,b,i);if i then k:=k+1;if odd(k)

                   then writeln(f1,b) else writeln(f2,b)

             end;{конец разделения} p:=r;i1:=false;i2:=false;if k>1 then

        begin {слияние файлов} rewrite(f);reset(f1);reset(f2);

               readln(f1,b1);readln(f2,b2);if more_less(b1,b2,p)

                      then write_str(f1,b1,i1) else write_str(f2,b2,i2);

               repeat if more_less(b1,b2,p) then if not eof(f1)

          then begin read_str(f1,b1,i1);if i1 then p:=not p;i1:=false end

          else p:=not p                              else if not eof(f2)

          then begin read_str(f2,b2,i2);if i2 then p:=not p;i2:=false end

          else p:=not p;

               if more_less(b1,b2,p) then write_str(f1,b1,i1)

                                                 else write_str(f2,b2,i2);

               until (i1 and i2);

        end{конец слияния файлов};

           until(k<=2);close(f);close(f1);close(f2);erase(f1);erase(f2);

      END{sort_file};

     END{s_text}.

program sort_page; { Сортировка текстового файла по страницам}

       uses s_text;

       var f,f_page,outf:text;{Файлы входной, страница и выходной}

              s,c,nm:string; p,pg,count,j:byte;

     

           begin {Ввод имени файла и открытие файла f}

                  repeat writeln('Введите имя исходного файла:');readln(nm);

                    assign(f,nm);{$I-}reset(f);{$I+}

                    if IOResult <>0 then

             begin writeln('Ошибка в имени файла');nm:='' end;

                  until not (nm=''){Конец открытия файла f};

                assign(f_page,'F_P');assign(outf,'OUTF');rewrite(outf);pg:=0;

                repeat rewrite(f_page);p:=0;

                       { Формирование страницы}

                       repeat readln(f,s);count:=0;

                          for j:=1 to length(s) do

                          if upcase(s[j]) in ['A'..'Z'] then inc(count);

                          str(count:2,c);s:=c+s;writeln(f_page,s);inc(p);

                       until (p=8) or eof(f);

                       inc(pg); for j:=1 to 30 do write(outf,' ');

                       writeln(outf,'-',pg,'-');

                       sort_file(f_page,true) { Конец формирования страницы};

            reset(f_page); {Перепись страницы в outf}

                                repeat readln(f_page,s);delete(s,1,2);writeln(outf,s);

                                until eof(f_page);writeln(outf,#12){ Конец переписи} ;

                until eof(f); close(outf);close(f_page);erase(f_page);

          end{sort_page}.

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

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

program clean_file;{ Чистка текстового файла от повторяющихся строк}

       var f,outf:text; {Входной и выходной файлы}

             nm,s,del_s:string; j,k,beg,c:integer; d,d1:Boolean;

       BEGIN writeln('ПРОГРАММА ЧИСТКИ ФАЙЛА');writeln;

          repeat write('Введите имя файла:');readln(nm);

 { Проверка существования и открытие файла f для чтения}

                       assign(f,nm);{$I-}reset(f);{$I+}

       if IOResult <>0 then begin writeln('Ошибка в имени файла');nm:='' end;

          until (nm<>'');k:=0; d:=true;c:=0; assign(outf,'OUTF');rewrite(outf);

          

       repeat {основной цикл}

                            readln(f,s);del_s:=s;reset(f);inc(k);beg:=1;

                { d:=false, если строка s повторяется }

                repeat readln(f,s);if (s=del_s) and (beg<k) then d:=false;inc(beg);

                until (eof(f) or (beg>k))  {конец d:=false};d1:=false;

      {d1:=true, если s cодержит символ-непробел}

                for j:=1 to length(del_s) do 

                    if del_s[j]<>' ' then d1:=true {конец d1:=true};

                 {Вывод неповторяющейся строки, отличной от строки пробелов}

                    if (d and d1) then writeln(outf,del_s);

                    if (not d) and d1 then

                 {Вывод повторяющейся строки, отличной от строки пробелов}

                      begin if c=0 then writeln('Повторяющиеся строки:');

                            writeln(del_s);inc(c);

                      end;  

                d:=true;

      until eof(f) {конец основного цикла};

                close(outf); if c=0 then writeln('Повторяющихся строк нет')

                                            else writeln('Всего ',c,' повторяющихся строк');

        END{clean_file}.

Заметим, что эта задача может быть решена более просто, если предварительно отсортировать файл, например, по возрастанию записей (в лексикографическом порядке строк).

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

Поиск, как правило, выполняется по заданным критериям (обычно представляющим некоторое логическое условие) и предполагает просмотр всего файла или его части. Эффективность поиска определяется его способностью просматривать минимум лишних записей (не удовлетворяющих критерию поиска). Поэтому для последовательных файлов поиску обычно предшествует процедура сортировки, позволяющая затем ограничить область поиска. Результатом поиска является выборка: это может быть либо фактографическая информация (набор записей или некоторых полей записей, удовлетворяющих критерию поиска) или статистическая информация (вычисления на наборе записей, удовлетворяющих критерию поиска). Гибкие средства поиска и выборки данных обычно реализуются системами управления базами данных (с использованием специализированных языков запроса, например SQL). Достаточно просто задачи поиска и выборки данных из файла программируются на Турбо Паскале. Пример программы выборки данных по запросу из файла записей о группе студентов (продолжающей пример, рассмотренный выше для задачи создания такого файла):

       program search;

       { Выборка из файла данных о группе студентов}

       uses CRT;

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

               gr_st=file of stud{данные о группе студентов};

        var gr:gr_st{группа студентов};

               st:stud{запись о студенте};

              nm:string{имя исходного файла};

           avr:string{условие для average};

           sgn:string[1]{знак в условии};ball:real{запрошенный балл};

           pr:boolean{признак выбранной записи};k:integer{кол-во выборок};

           er:integer{ошибка преобразования в число};

        BEGIN clrscr;repeat {открытие файла на чтение}

                     write('Введите имя файла:'); readln(nm);

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

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

                               until nm<>''; {анализ запроса }

           repeat write('Введите запрос для среднего балла: ');readln(avr);

              sgn:=copy(avr,1,1);avr:=copy(avr,2,length(avr)-1);

              val(avr,ball,er); if er<>0 then ball:=0;

           until (ball>=2)and(ball<=5); k:=0; writeln('Запрошенные данные:');

                  repeat {реализация запроса к файлу nm}

           read(gr,st);with st do

           begin if sgn='>' then pr:=average>ball else pr:=average<=ball;

           if pr then begin writeln(name,average:1:2);inc(k);delay(1000) end

           end until eof(gr);if k<>0 then writeln('Всего студентов: ',k)

                                                  else writeln('Пустая выборка');readkey

        END {search}.

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

Вывод файла на печать - один из завершающих этапов обработки данных, предоставляющий информацию пользователям в удобной форме. Форматирование выводимых данных - важнейшая особенность программ печати. Большие возможности по форматированию документальной информации предоставляют текстовые редакторы, системы управления базами данных, генераторы отчётов. Для того чтобы продемонстрировать возможности форматирования данных средствами Турбо Паскаля приведем простую программу постраничной печати текстового файла в двух вариантах:

      

       program print_text; {Печать текстового файла}

       uses Printer;

       var f:text; {Исходный файл}

             c:char;s,nm:string;

              j,p:word;

       const bel=#7;FF=#12;

       BEGIN writeln('ПЕЧАТЬ ТЕКСТА ');writeln;write('Имя файла:');readln(nm);

             if nm<>'' then

             begin {открытие f с контролем существования файла}

                    assign(f,nm);{$I-} reset(f);{$I+}

                if IOResult<>0 then begin writeln('Ошибка');halt end {конец открытия f} ;

                j:=1;p:=1;repeat  {цикл печати}if j mod 50=0 then

                begin writeln(LST,FF);writeln(bel,'Конец страницы ',p:3);

                     writeln('Печатать следующую страницу(Y/N)?',bel);

                     readln(c);if upcase(c)<>'Y' then

                     begin close(f);halt end;p:=p+1;

  for j:=1 to 35 do

                           write(LST,' ');writeln(LST,'-',p,'-');j:=1

                end;readln(f,s);writeln(LST,s);inc(j);

                               until eof(f) {конец цикла печати};writeln(LST,FF);close(f)

             end

       END{print_text}.

        program print_text2;

       {Вариант программы print_text с выводом LST на экран}

       var f,LST:text;c:char;s,nm:string;j,p:word;

       const bel=#7;FF=#12;

       BEGIN writeln('ПЕЧАТЬ ТЕКСТА ');writeln;

             write('Имя файла:');readln(nm);if nm<>'' then

           begin assign(f,nm);{$I-} reset(f);{$I+}

                   if IOResult<>0 then begin writeln('Ошибка');halt end;

                   assign(LST,'con');rewrite(LST);j:=1;p:=1;

                   repeat if j mod 50=0 then

               begin writeln(LST,FF);writeln(bel,'Конец страницы ',p:3);

                     writeln('Печатать следующую страницу(Y/N)?',bel);

                     readln(c);if upcase(c)<>'Y' then

                     begin close(f);halt end;p:=p+1;for j:=1 to 35 do

                           write(LST,' ');writeln(LST,'-',p,'-');j:=1

               end;readln(f,s);writeln(LST,s);inc(j);

                   until eof(f);writeln(LST,FF);close(f)

           end

       END{print_text2}.  

       


 

А также другие работы, которые могут Вас заинтересовать

63819. Охрана материнства и детства — приоритетное направление здравоохранения 30 KB
  Показатели здоровья женщин и детей являются наиболее чувствительным индикатором социально-экономического развития общества. Деятельность государственной системы охраны материнства и детства направлена на реализацию комплекса социально-экономических и лечебно-профилактических мер...
63820. Родильный дом 30 KB
  Стационар родильного дома имеет следующие подразделения: 1 приемно-пропускной блок; 2 родовые отделения; 3 послеродовое физиологическое первое акушерское отделение 50 55 акушерских коек; 4 обсервационное второе акушерское отделение 20 25 акушерских коек...
63821. Женская консультация 28.5 KB
  Основными задачами женской консультации являются: проведение профилактических мероприятий направленных на предупреждение осложнений беременности родов послеродового периода гинекологических заболеваний; оказание лечебно-гинекологической помощи...
63822. Показатели работы женской консультации и роддома 24 KB
  Деятельность женской консультации оценивается по следующим показателям: своевременность обращения беременных до 12 недель отношение числа женщин поступивших под наблюдение в сроки до 12 недель к общему числу беременных умноженное на 100...
63824. Медицинская документация и показатели, характеризующие деятельность поликлиники и стационара детской городской больницы 22.5 KB
  Деятельность детской поликлиники оценивается по данным отчета-вкладыша €œО медицинской помощи детям первичной медицинской документации: показатели организации патронажа дородового отношение числа детей матери...
63825. Организация санитарно-эпидемиологической службы в России 47.5 KB
  Эрисман создал первую санитарную станцию в Москве в 1891г. Первым санитарным врачом был Мадисон. После ВОВ создана единая комплексная СЭСл до этого санитарная эпидемическая.
63827. Трудоспособность, понятие. Временная нетрудоспособность 25 KB
  Виды нетрудоспособности: временная стойкая длительная инвалидность. При полной временной нетрудоспособности любая работа полностью противопоказана и больной нуждается в создании определённых условий.