Теория. Работа с файлами в Pascal, С++ и Python

1. Создание файловых объектов

Ниже рассматривается работа только с текстовыми файлами, поскольку на КЕГЭ бинарные (типизированные) файлы не используются.
Создание файлового объекта в Pascal

Необходимо выполнить следующие шаги:

  • Объявить файловую переменную
  • Связать эту переменную с конкретным файлом
  • Открыть файл в соответствующем режиме
  • После выполнения задач, разорвать связь файловой переменной с файлом
Фрагмент программы на Pascal
FreePascal
var
    // Объявляем файловые переменные
    fin, fout: text; 
begin
    // Связываем файловые переменные с файлами 
    assign(fin,'input');
    assign(fout,'output');
    // Открываем файл в режиме чтения
    reset(fin);
    // Открываем файл в режиме записи
    rewrite(fout)

    // Решаем поставленную задачу ...
    
    // Закрываем (разрываем связь) работу с файлами
    close(fin); 
    close(fout);
end.

Что нужно знать:

  • В качестве аргумента, в функцию assign(), можно передавать как полный, так и относительный путь.
  • Файл, открываемый функцией reset(), должен существовать в системе.
  • Файл, открываемый функцией rewrite(), будет создан или перезаписан, если файл по этому пути уже существует.
  • При разрыве связи файловой переменной с файлом (с помощью функции close()) она остается доступной и может быть вновь связана с тем же или другим файлом.
Создание файлового объекта в C++

Необходимо выполнить следующие шаги:

  • Включить заголовочный файл STD файловых потоков
  • Создать объект файлового потока ввода или вывода, с указанием режима открытия файла (необязательно, по умолчанию режим текстовый)
  • Открыть поток файлового ввода или вывода
  • После выполнения задач, разорвать связь файлового объекта с файлом
Фрагмент программы на С++
C++
// Включаем заголовочный файл файловых потоков
#include <fstream>
using namespace std;
 
int main() {
    // Создаем файловый объект ввода (чтение файла)
    ifstream fin;
    fin.open("input"); // по умолчанию, текстовый режим
    // Эти две инструкции можно объединить:
    // ifstream fin("input");

    // Создаем файловый объект вывода (запись в файл)
    ofstream fout;
    fout.open("output");
    // Аналогично: ofstream fout("output");

    // Решаем поставленную задачу ...

    // Разрываем связь с файлами, но потоковые объекты не удаляются!
    fin.close();
    fout.close();
    return 0;
}  
В данном примере потоковые объекты однонаправленные. Т. е., повторно потоковый объект ввода (например) можно связать с файлом из которого осуществляется чтение (и только!). Аналогично для объекта выходного потока. Чтобы потоковый объект можно было использовать в обоих направлениях необходимо применить соответствующий класс и открывать файл одновременно и для чтения, и для записи:

// fin можно использовать как для чтения, так и для записи
fstream fin("input", ios::out | ios::in);

Правда, на экзамене это не пригодится!

Создание файлового объекта в Python

В Python объявление файловой переменной, связывание её с файлом и указание режима (по умолчанию, чтение файла) производится в одной инструкции.

Фрагмент программы на Python
Python
# Создаем файловый объект ввода (чтение файла)
fin = open('input') # Режим чтения, по умолчанию
# Создаем файловый объект вывода (запись в файл)
fout = open('output', 'w') # Вторым аргументом указываем режим ('w' - режим записи)

# Решаем поставленную задачу ...

# Разрываем связь с файлами, но потоковые объекты не удаляются!
fin.close() 
fout.close()

2. Чтение (ввод) и запись (вывод) в файл

У каждого файлового объекта есть два ассоциированных с ним значения, называемые указатель чтения и указатель записи. Эти значения определяют номер байта (или символа) относительно начала файла, с которого будет производиться чтение или запись. Следовательно запись символа или блока сдвигает указатель на определенную позицию. Функции, обеспечивающие запись (вывод) в файл поддерживают форматированный вывод, аналогичный форматированному выводу стандартного потока (на экран).
Для текстовых файлов актуально только построчное чтение (или запись) файла. За чтение строки файла отвечают стандартные процедуры (операции или функции) языка. Рассмотрим как осуществляется чтение и запись в файл на примере простой задачи.
Задача 1. Дан файл input, в первой строке которого записаны два целых числа, разделенных пробелом. Записать сумму этих чисел в другой файл – output.

Запись и чтение в Pascal

Используются следующие функции:

  • writeln(fout, args) – записывает (выводит) в файл fout аргументы args (значения переменных и констант);
  • readln(fin, args) – читает строку из файла fin и вводит значения, полученные из строки (разбивается по пробельным символам) в переменные args
Программа #1 на Pascal
FreePascal
var
    fin, fout: text; 
    a, b: integer;
begin
    assign(fin,'input');
    assign(fout,'output');
    reset(fin);
    readln(fin, a, b);
    rewrite(fout);
    writeln(fout, a + b);
    close(fin); 
    close(fout);
end.
Вариант с одной файловой переменной
var
    f: text; 
    a, b: integer;
begin
    assign(f,'input');    
    reset(f);
    readln(f, a, b);
    close(f); 
    assign(f,'output2');
    rewrite(f);
    writeln(f, a + b);
    close(f);
end.
Запись и чтение в C++

Используются следующие операции:

  • >> – операция ввода (извлечения);
  • << - операция вывода (вставки)
Эти операции применяются аналогично соответствующим операциям стандартного потока (iostream).

Программа #1 на С++
C++
#include <fstream>
using namespace std;
 
int main() {
    int a, b;
    ifstream fin("input");
    ofstream fout("output");
    fin >> a >> b;
    fout << a + b << endl;
    fin.close();
    fout.close();
    return 0;
}
Обратите внимание, что для Pascal и C++ данные, в момент присваивания переменным, преобразуются к соответствующему типу данных этих переменных, поскольку это строго типизированные языки. Что качается Python, то данные, в любом случае, необходимо преобразовать к нужному типу "в ручную".
Запись и чтение в Python

Используются следующие методы:

  • readline() – функция (метод) чтения файла (ввода), читает текущую строку файла полностью, до символа перевода на новую строку, и возращает эту строку;
  • write() – функция (метод) вывода в файл, выводимые данные необходимо преобразовывать в тип str (строка)
Программа #1 на Python
Python
f = open('input')
s = f.readline().split()
# Использование функции преобразования (int) обязательно!
sum = int(s[0]) + int(s[1]) 
f.close()
f = open('output', 'w')
# Использование функции преобразования (str) обязательно!
f.write(str(sum))
f.close()

3. Построчное чтение файла

Для организации чтения всех существующих строк в файле в Pascal и C++ используется цикл while и функция eof(). Логическая функция eof() возвращает значение true, если файловый указателть достиг конца файла. Поскольку, как мы знаем, указатель чтения перемещается к следующей строке после каждого вызова соответствующей функции, можно организовать цикл while, в условии которого будет использоваться функция eof() с логической операцией not (отрицание). Посмотрим как организовано построчное чтение файла в трех языках на примере простой задачи.

Обратите внимание, что в python функции eof() нет, т. к. файловый объект является итерируемым. Подробности см. ниже.

Задача 2. Дан файл input, в каждой строке которого записано целое число. Получить среднее арифметическое этих чисел и записать это значение в файл output.

Построчное чтение файла в Pascal
Если, по каким-либо причинам, вам необходимо пропустить строку в файле (иными словами, перевести указатель на следующую строку), то можно вызвать функцию readln(fin) без аргументов.
Программа #2 на Pascal
FreePascal
uses
    crt;
var
    i, d: integer;
    s: real;
    fin, fout: text;
begin
    clrscr;
    assign(fin,'input');
    assign(fout,'output'); 
    reset(fin);
    i := 0;
    s := 0;
    // Организуем цикл по файлу
    while not(eof(fin)) do
    begin
        // Читаем очередную строку
        readln(fin, d);
        s := s + d;
        inc(i);
    end;
    close(fin);   
    rewrite(fout);
    // Выводим среднее арифметическое в файл output
    writeln(fout, s / i); 
    close(fout);
end.
Построчное чтение файла в C++

В C++ метод eof() сообщает о состоянии потока. Поскольку чтение последней строки файла было успешным, то eof() не изменяет своего значения (false) и цикл выполняет еще один шаг (но уже лишний для нас, так как в конце файла нет данных) и только потом eof() принимает значение true. Лишний шаг в нашей программе - это безусловно ошибочный результат, поэтому нужно проконтролировать: действительно ли все данные прочитаны (т. е. мы получили последнюю строку)? Это делается путем добавления инструкции if с инструкцией break в тело цикла. Вариант программы с eof() приведен ниже под спойлером.
Но на практике поступают иначе! Сам потоковый объект (fin) и операция ввода (>>) помещается в условие цикла, где будет проверяться наличие данных в потоке (а не его состояние). Это делает программу значительно компактнее.

Программа #2 на С++
C++
#include <fstream>
using namespace std;
 
int main() {
	int i = 0, d = 0; 
	double s = 0.;
    ifstream fin("input");
    ofstream fout("output");
    while (fin >> d) {
        s += d;
        i++;
    }
    fin.close();
    fout << s / i << endl;
    fout.close();
    return 0;
}
Вариант с методом eof()
#include <fstream>
using namespace std;
 
int main() {
	int i = 0, d = 0; 
	double s = 0.;
    ifstream fin("input");
    ofstream fout("output");
    while (!fin.eof()) {
        fin >> d;
        if (!fin) break;
        s += d;
        i++;
    }
    fin.close();
    fout << s / i << endl;
    fout.close();
    return 0;
}
Построчное чтение файла в Python

Для организации работы с файловыми объектами в Python используется менеджер контекста with-as. При этом, метод close() не используются - работа с файлами завершается автоматически. Однако менеджер контекста - это всего лишь метод организации кода, поэтому вы можете его и не использовать, а подходить к работе с файлом так, как показано выше (закрывая файл "в ручную"). Поскольку файловый объект в Python является итерируемым (строки файла можно представить как элементы массива), то для построчного чтения файла используется цикл for по последовательности.

Программа #2 на Python
Python
s = 0.
i = 0
with open('input') as f:
    for d in f: # Итерация по файлу
        s += int(d)
        i += 1
with open('output', 'w') as f:
	f.write(str(s / i))

Ссылки

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.


Обсуждение закрыто.