#20 Чтение данных -- Работа с файлами в Паскаль, assign, reset

(урок в процессе разработки)

В этом уроке мы рассмотрим примеры работы с текстовыми файлами (а именно способы чтения данных) средствами ЯП Паскаль.

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

Где сохранить текстовый файл

(определим его адрес в файловой системе)

Самый простой способ разместить файл -- положить его в ту же папку, в которой лежит исполняемый файл вашего проекта. Определить путь к этой папке можно выполнив код:

begin
  WriteLn('Put k failu programmy: ');
  WriteLn(ParamStr(0));
  readln();
end.

На экран вам будет выведено что-то вроде (у вас этот путь может быть другим -- действуйте по аналогии):

Put k failu programmy: 
C:\Users\TEMP.UIC.012\Documents\project1.exe

Получается, что директория:

C:\Users\TEMP.UIC.012\Documents

скорее всего доступна для размещения файлов, и потому в ней создадим файл с именем input.txt, который можно будет прочитать, то есть полный путь к нему будет:

C:\Users\TEMP.UIC.012\Documents\input.txt

ПРИМЕЧАНИЕ: убедитесь, что в вашей системе отображается расширение файлов -- иначе на деле может оказаться, что ваш файл называется не input.txt, а input.txt.txt

Чтение файлов

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

Var
    f1:text; // тип для открытия текстового файла
    filename, s: string;
begin
  filename := 'C:\Users\TEMP.UIC.012\Documents\input.txt'; // путь к файлу

  assign(f1, filename); { связывание переменной дескриптора
                        с путём к файлу }
  reset(f1); // открываем файла для чтения

  writeln('========nachalo faila=====');
  while not eof(f1) do // пока не достигнут конец файла
    begin
      readln(f1, s);  // читаем из него очередную строку
      writeln(s); // и выводим её в консоль
    end;
  writeLn('========= konez faila =========');

  readln();
end.

Примеры

Пример №1 -- чтение содержимого файла с проверкой существовования

Var
    f1:text; // тип для открытия текстового файла
    filename, s: string;
begin

  filename := 'C:\Users\TEMP.UIC.012\Documents\input.txt'; // путь к файлу
  //filename := 'D:\tmp\my\input.txt'; // путь к файлу

  WriteLn('Put k failu programmy: ');
  WriteLn(ParamStr(0));

  assign(f1, filename);
  {$I-} reset(f1);  {$I+}  // попытка открыть файл на чтение с подавлением ошибки
  if IOResult <> 0 then    // если есть ошибки
  begin
    writeLn('File ', filename, ' ne naiden!');
  end else  // если удалось открыть на чтение
  begin
    writeLn('File ', filename, ' suchectvuet. I vot ego soderzimoe:');
    while not eof(f1) do
      begin
        readln(f1, s);
        writeln(s);
     end;
   end;
  writeLn('========= konez faila =========');

  readln();
end.       

Ещё примеры

  1. Проверка существования файла
  2. Фукция ParamStr() -- Путь к файлу и папке программы, определить откуда происходит запуск

Задачи /(самостоятельная работа)

  1. Создайте файл в вашей операционной системе и выведите в консоль всё его содержимое.
  2. У вас есть текстовый файл с информацией об итогах соревнований (каждая строка имеет формат: имя + произвольное число пробелов + балл 1 + произвольное число пробелов + балл 2):
    Вася    16     485
    Коля    17   555
    Юра     18   61
    ..........
    

    -- где:
    слева указаны имена участников, а справа число баллов.
    Первое число в каждой строке -- штрафные баллы набранные участниками, а второе число -- "положительные баллы", то есть если у нас есть строка:

    Vasya    N      M

    где $N$ -- число шрафных баллов, а $M$ - число баллов положительных, то итоговая оценка Васи $Z$ вычисляется как разность:
    $$Z = M - N.$$
    Напишите программу, которая определяет победителя и его итоговый балл (прочитав данный файл построчно).
    По возможности разбивайте код на процедуры и функции.

  3. Имеется текстовый файл в котором содержится не более 30 строк, в каждой строке не более 30 символов (пробелы тоже считаются символами). Цифры и другие символы перемешаны в каждой строке.

    Задание: найдите максимальное число, c учетом того, что числом считаются подряд идущие цифры не только по горизонтали, но и по вертикали.

    Примеры:

    1. fsd334rgd
      rfg46gdfg
      ter5tge56
      123gergf

      Ответ: 345

    2. fsd334rgd
      r      fg
      ter5tge56
      123gergf
      

      Ответ: 334

    3. fsd334rgd
      r16hyj3f7
      23tge6f57
      123gergf7
      

      Ответ: 777

    4. 
                \|/
              -->*<--
                /o\
               /_\_\
              /_/_0_\
             /_o_\_\_\
            /_/_/_/_/o\
           /@\_\_\@\_\_\
          /_/_/O/_/_/_/_\
         /_\_\_\_\_\o\_\_\
        /_/0/_/_/20_/_/@/_\
       /_\_\_\_\_0_\_\_\_\_\
      /_/o/_/_/@/2/_/o/_/0/_\
               [_1_]
      

      Ответ: 2021

    ПРИМЕЧАНИЕ: задача взята из списка соревнования IFF 2020

  4. Дан текстовый файл, в котором с в ASCII-стиле нарисованы цепочки из цифр, которые связаны по горизонтали и вертикали.
    Все цепочки составляют одно дерево, которое устроено так:
    • всегда есть общий корень и это цифра
    • по горизонтали цепочка не разрывается пробелами, соединяется же с помощью последовательностей знака - (тире).
    • по вертикали цепочка не разрывается переносом строк, соединяется же с помощью вертикальных последовательностей символа | (вертикального разделителя).

    Размер схемы не более чем 100 на 100 символов.

    Примеры:

    1. 1------4--------------5-------6--------7
             |              |
             |              |-------5---------8
             |
             |-------6--------7--7-------9------8---1----5---3
      

      Ответ: 10

    2. 1------4------8--------5-------6--------7
             |      |        |
             |      |        |-------5---------8
             |      |                
             |      |--------8-8-8---8----8
             |     
             |-------6--------7--7
             |--------------5-5--5--5  
      

      Ответ: 8

    ПРИМЕЧАНИЕ: задача взята из списка соревнования IFF 2020

    Задача: вывести длина самой длинной цепочки.

Источники (что ещё почитать)