Pascal: Занятие № 12 Часть2. Работа с файлами в паскале (типизированные файлы)

На занятии будет рассмотрена работа с типизированными файлами в Паскале и разобраны конкретные решенные примеры задач

Типизированные файлы в Паскаль

Типизированный файл может быть описан как файл любого типа (кроме типа file). Описывают подобный файл словосочетанием file of с последующим указанием типа компонентов файла.

Файл с типом, т.е. типизированный файл состоит из последовательности записей (компонент), имеющих одинаковую длину и одинаковый внутренний формат.

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

При последовательном доступе записи (компоненты) размещаются в файле последовательно в порядке их поступления.

При прямом доступе данные размещаются в определенных областях, имеющих последовательную нумерацию, и начинаются с нуля. Движение по записям осуществляется посредством так называемого указателя, перемещение которого осуществляется при помощи процедур (seek pascal). После открытия файла указатель (номер текущей компоненты) стоит в самом начале, т.е. на нулевом компоненте. После каждого прочтения или записи указатель сдвигается к следующему компоненту.

Описание:

  1. var
       f1: file of char;
       f2: file of integer;
  2. type t = file of real;
    var f: t;
  3. type st = record
            a: string[10];
            b: integer;
    end;
    var dan: file of st;
    </ol>

Открытие файла

Reset (f);
Rewrite (f);
Append (f);

Чтение из текстового файла

Read (f, список переменных);

Запись в текстовый файл

Write (f, список переменных);
WriteLn (f, список переменных);

Процедуры работы с файлом

Смещение указателя файла:
Процедура seek в Паскаль смещает указатель файла f на n-ную позицию. Используется при прямом доступе к файлу:

Seek(f, n);

Процедура возвращающая размер файла:

filesize (f);

функция проверки конца файла:

EOF(f);

Символьные и строковые файлы (типизированные)

Последовательный доступ

Пример: (последовательный доступ) Посимвольно считывать данные из файла и выводить их на экран – каждый символ с новой строки
1
2
3
4
5
6
7
8
9
10
11
12
13
var
    f: file of char;
    c: char;
begin
    assign (f, 'c:\file.txt');
    reset (f);
    while not eof (f) do begin {пока не достигнут конец файла}
        read (f, c);
        writeln (c);
    end;
close (f);
readln
end.
Пример: (последовательный доступ) Записывать в файл определенное кол-во символов (символы и их количество вводит пользователь)
Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var
    f: file of char;
    c: char;
    i, n: byte;
begin
    assign (f, 'c:\file.txt');
    rewrite (f);
 
    write ('Количество символов: ');
    readln (n);
 
    for i:=1 to n do begin
        write ('Введите символ: ');
        readln (c);
        write (f, c);
    end;
close (f);
end.
Пример: (последовательный доступ) Дан символьный файл, содержащий, по крайней мере, один символ пробела. Удалить все его элементы, расположенные после первого символа пробела, включая и этот пробел.

* Предварительно следует программно записать в исходный файл символы

Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var
 F_in,F_out: File of Char;
 a,C:Char;
 i:integer;
begin
  Assign(F_in,'c:\text.txt');
  ReWrite(F_in);
  write('Какие символы записываем в исходный файл?');
  for i:=1 to 5 do
  begin
       read(a);
       write(F_in,a);
  end;
 
  Reset(F_in);
  Assign(F_out,'c:\text1.txt');
  ReWrite(F_out);
 
  Read(F_in,C);
  while (not eof(F_in)) and (C<>' ') do
   begin
    Write(F_out,C);
    Read(F_in,C);
   end;
   Close(F_out);
   Close(F_in);
   Erase(F_in);
   Rename(F_out,'c:\text.txt');
end.
pascal file string1. Дан символьный файл, содержащий, по крайней мере, один символ пробела. Удалить все его элементы, расположенные после последнего символа пробела, включая и этот пробел.

Пример: Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наименьшей длины (в том же порядке).

Пример:

Введите строки исходного файла:
первая строка
вторая строка длинная
третья строка
строка
пятая строка

результирующий файл:
строка

Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var
 S: String;
 F_in,F_out: file of string;
 MinLen: integer;
  i:integer;
begin
  Assign(F_in,'c:\text.txt');
  Rewrite(F_in);
   write('Введите строки исходного файла:');
  for i:=1 to 5 do
  begin
       read(s);
       write(F_in,s);
  end;
  Reset(F_in);
  Assign(F_out,'c:\text1.txt');
  Rewrite(F_out);
 
 MinLen:=-1;
 
 
 while (not eof(F_in)) do
  begin
   Read(F_in,S);
   if (Length(S)<MinLen) or (MinLen=-1) then
   MinLen:=Length(S);
  end;
 
 Close(F_in);
 Reset(F_in);
 
 
 while (not eof(F_in)) do
  begin
   Read(F_in,S);
   if Length(S)=MinLen then
   Write(F_out,S);
  end;
 
 Close(F_in);
 Close(F_out);
end.
pascal file string2. Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наибольшей длины (в обратном порядке).

Числовые файлы (типизированные)

Последовательный доступ

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

Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var
 S,s1:String;
 F_in,F_out: File of Integer;
 k,i:integer;
 a:array[1..100] of integer;
begin
  S:='c:\text.txt';
  Assign(F_in,S);
  rewrite(F_in);
  for i:=1 to 10 do
      write(F_in,i); {записываем в исходный файл числа}
  close(F_in);
  Reset(F_in);
  S1:= 'c:\text1.txt';
  Assign(F_out,S1);
  ReWrite(F_out);
 
  k:=1;
  writeln('считанные из файла числа:');
   while (not eof(F_in)) do
   begin
    Read(F_in,a[k]);
    writeln(a[k]);
    k:=k+1;
   end;
  Close(F_in);
writeln('записываемые числа в файл');
 for i:=k-1 downto 1 do
   begin
    Write(a[i]:3);
    Write(F_out,a[i]);
   end;
 
 Close(F_out);
end.
pascal file 2. Дан файл вещественных чисел. Создать два новых файла, первый из которых содержит элементы исходного файла с нечетными номерами (1,3,…), а второй — с четными (2,4,…).
Внимание: числа в исходном файле должны быть записаны программно! Иначе считывание будет происходить неверно.

pascal file 3. Дан файл вещественных чисел. Найти сумму его элементов с четными номерами.
Внимание: числа в исходном файле должны быть записаны программно! Иначе считывание будет происходить неверно.

Пример: Дан файл вещественных чисел. Найти его первый локальный минимум (локальным минимумом называется элемент, который меньше своих соседей).

* Для решения не использовать массивы.

Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var
 S:String;
 F_in: File of Real;
 El2,El1,El:Real;
 i:integer;
 a:real;
 
begin
  Assign(F_in,'c:\text.txt');
  rewrite(F_in);
  writeln ('Введите вещественные числа');
  for i:=1 to 5 do begin
      read(a);
      write(F_in,a); {заполняем исходный файл числами}
  end;
  close(F_in);
  Reset(F_in); 
  Read(F_in,El);
  Read(F_in,El1);
  Read(F_in,El2);
  writeln('Результат =');
  if (El1<El)and(El1<El2) then Writeln('s',El1:4:2)
  else
   begin
    while (not eof(F_in)) and not((El>El1) and (El1<El2)) do
     begin
      El:=El1;
      El1:=El2;
      Read(F_in,El2);
     end;
    if (El>El1) and (El1<El2) then
       Writeln(El1:4:2)
    else if eof(F_in) and (El1>El) then
       Writeln(El:4:2);
   end;
  Close(F_in);
end.
pascal file 4. Дан файл вещественных чисел. Найти его последний локальный максимум (локальным максимумом называется элемент, который больше своих соседей).

Пример:
Дан файл вещественных чисел. Заменить в нем все элементы на их квадраты.

* Перед выполнением программы необходимо узнать в какой папке сохраняются файлы, созданные программой ABC.

Показать решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var
 S:String;
 F_in,F_temp: File of Real;
 temp:Real;
begin
    Assign(F_in,'\text.txt');
  Reset(F_in);
  Assign(F_temp,'\text1.txt');
  ReWrite(F_temp);
  while (not eof(F_in)) do
   begin
    Read(F_in,temp);
    temp:=sqr(temp);
    Write(F_temp,temp);
   end;
 
  Close(F_in);
  Close(F_temp);
  Erase(F_in); {удаление файла}
  Rename(F_temp,'\text.txt'); {Переименование файла}
end.

Здесь следует обратить внимание на то, что файлы, скорее всего, сохраняются в папке : C:\Users\имя пользователя\AppData\Local\VirtualStore

pascal file 5. Дан файл вещественных чисел. Поменять в нем местами минимальный и максимальный элементы.
Алгоритм:

  • найти в исходном файле минимальный элемент, сохранить его и его индекс в переменные;
  • найти в исходном файле максимальный элемент, сохранить его и его индекс в переменные;
  • создать временный файл и переписать туда элементы исходного файла кроме тех позиций, на которых должны стоять максимальный и минимальный элементы; в указанные позиции разместить элементы, поменяв их местами.
  • Прямой доступ

    Пример: (прямой доступ) В файле заменить символ определенной позиции. Позицию символа и сам новый символ запросить у пользователя. Использовать процедуру seek Паскаль
    Показать решение:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    var
        f: file of char;
        c: char;
        n: integer;
    begin
        assign (f, 'c:\text.txt');
        reset (f);
        write('Введите позицию: ');
        readln(n);
        seek(f,n);
        write('Введите новый символ: ');
        readln(c);
        write(f,c);
        close(f);
     end.
    Задание: (прямой доступ) В файле заменить символы с четной позицией на восклицательные знаки (‘!’). Использовать процедуру seek