
- •Лекция 1 Основы алгоритмизации
- •1.1 Языки программирования
- •1.2 Этапы решения задач на компьютере
- •1.3 Понятие алгоритма и его свойства
- •1.4 Графическое описание алгоритмов. Схемы алгоритмов
- •Блоки для изображения схем алгоритмов и программ
- •1.5 Типы алгоритмов
- •Лекция 2 Начальные сведения о языке
- •2.3 Компиляция и выполнение программы
- •Лекция 3 Имена, переменные и константы
- •3.1 Имена
- •3.2 Переменные
- •3.3 Константы
- •Лекция 4 Операции и выражения
- •4.1 Выражения
- •4.2 Операция присваивания
- •4.3.1 Арифметические операции
- •4.3.2 Операции сравнения
- •4.4 Порядок вычисления выражений
- •Лекция 5 Операторы
- •5.1 Что такое оператор
- •5.1.1 Операторы-выражения
- •5.1.2 Объявления имен
- •5.1.3 Операторы управления
- •5.1.3.1 Условные операторы
- •5.1.3.2 Операторы цикла
- •5.1.3.3 Оператор возврата
- •5.1.3.4 Оператор перехода
- •Лекция 6 Функции
- •6.1 Вызов функций
- •6.2 Имена функций
- •6.3 Необязательные аргументы функций
- •6.4 Рекурсия
- •Лекция 7 Встроенные типы данных
- •7.1 Общая информация
- •7.2 Целые числа
- •7.3 Вещественные числа
- •7.4 Логические величины
- •7.5 Символы и байты
- •7.6 Кодировка, многобайтовые символы
- •7.7 Наборы перечисляемых значений
- •Лекция 8 Классы и объекты
- •8.1 Понятие класса
- •8.2 Определение методов класса
- •8.3 Переопределение операций
- •8.4 Подписи методов и необязательные аргументы
- •8.4.1 Запись классов
- •Лекция 9 Производные типы данных
- •9.1 Массивы
- •9.2 Структуры
- •9.2.1 Битовые поля
- •9.3 Объединения
- •9.4 Указатели
- •9.4.1 Адресная арифметика
- •9.4.2 Связь между массивами и указателями
- •9.4.3 Бестиповый указатель
- •9.4.4 Нулевой указатель
- •9.5 Строки и литералы
- •Лекция 10 Распределение памяти
- •10.1 Автоматические переменные
- •10.2 Статические переменные
- •10.3 Динамическое выделение памяти
- •10.4 Выделение памяти под строки
- •10.5 Рекомендации по использованию указателей и динамического распределения памяти
- •10.6 Ссылки
- •10.6 Распределение памяти при передаче аргументов функции
- •10.6.1 Рекомендации по передаче аргументов
- •Лекция 11 Производные классы, наследование
- •11.1 Виртуальные методы
- •11.1.1 Виртуальные методы и переопределение методов
- •11.2 Преобразование базового и производного классов
- •11.3 Внутреннее и защищенное наследование
- •11.4 Абстрактные классы
- •11.5 Множественное наследование
- •11.5.1 Виртуальное наследование
- •15.2 Проблема использования общих функций и имен
- •15.3 Использование включаемых файлов
- •15.4 Препроцессор
- •15.4.1 Определение макросов
- •Условная компиляция
- •15.4.2 Дополнительные директивы препроцессора
- •Лекция 16 Определение, время жизни и области видимости переменных в больших программах
- •16.1 Файлы и переменные
- •16.1.1 Общие данные
- •16.1.2 Глобальные переменные
- •16.1.3 Повышение надежности обращения к общим данным
- •16.2 Область видимости имен
- •16.3 Оператор определения контекста namespace
- •Лекция 17 Обработка ошибок
- •17.1 Виды ошибок
- •17.2 Возвращаемое значение как признак ошибки
- •17.3 Исключительные ситуации
- •17.3.1 Обработка исключительных ситуаций
- •17.3.2 Примеры обработки исключительных ситуаций
- •Лекция 18 Bвод-вывод
- •18.1 Потоки
- •18.3 Манипуляторы и форматирование ввода-вывода
- •18.4 Строковые потоки
- •18.5 Ввод-вывод файлов
- •Лекция 19 Шаблоны
- •19.1 Назначение шаблонов
- •19.2 Функции-шаблоны
- •19.3 Шаблоны классов
- •19.3.1 "Интеллигентный указатель"
- •19.3.2 Задание свойств класса
- •Список использованных источников
- •Содержание
18.5 Ввод-вывод файлов
Ввод-вывод файлов может выполняться как с помощью стандартных функций библиотеки Си, так и с помощью потоков ввода-вывода. Функции библиотеки Си являются функциями низкого уровня, без всякого контроля типов.
Прежде чем перейти к рассмотрению собственно классов, остановимся на том, как осуществляются операции ввода-вывода с файлами. Файл рассматривается как последовательность байтов. Чтение или запись выполняются последовательно. Например, при чтении мы начинаем с начала файла. Предположим, первая операция чтения ввела 4 байта, интерпретированные как целое число. Тогда следующая операция чтения начнет ввод с пятого байта, и так далее до конца файла.
Аналогично происходит запись в файл – по умолчанию первая запись производится в конец имеющегося файла, а все последующие операции записи последовательно пишут данные друг за другом. При операциях чтения-записи говорят, что существует текущая позиция, начиная с которой будет производиться следующая операция.
Большинство файлов обладают возможностью прямого доступа. Это означает, что можно производить операции ввода-вывода не последовательно, а в произвольном порядке: после чтения первых 4-х байтов прочесть с 20 по 30, затем два последних и т.п. При написании программ на языке Си++ возможность прямого доступа обеспечивается тем, что текущую позицию чтения или записи можно установить явно.
В библиотеке Си++ для ввода-вывода файлов существуют классы ofstream (вывод) и ifstream (ввод). Оба они выведены из класса fstream. Сами операции ввода-вывода выполняются так же, как и для других потоков – операции >> и << определены для класса fstream как "ввести" и "вывести" соответствующее значение. Различия заключаются в том, как создаются объекты и как они привязываются к нужным файлам.
При выводе информации в файл первым делом нужно определить, в какой файл будет производиться вывод. Для этого можно использовать конструктор класса ofstream в виде:
ofstream(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Первый аргумент – имя выходного файла, и это единственный обязательный аргумент. Второй аргумент задает режим, в котором открывается поток. Этот аргумент – битовое ИЛИ следующих величин:
ios::app |
при записи данные добавляются в конец файла, даже если текущая позиция была перед этим перемещена; |
ios::ate |
при создании потока текущая позиция помещается в конец файла; однако, в отличие от режима app, запись ведется в текущую позицию; |
ios::in |
поток создается для ввода; если файл уже существует, он сохраняется; |
ios::out |
поток создается для вывода (режим по умолчанию); |
ios::trunc |
если файл уже существует, его прежнее содержимое уничтожается, и длина файла становится равной нулю; режим действует по умолчанию, если не заданы ios::ate, ios::app или ios::in; |
ios::binary |
ввод-вывод будет происходить в двоичном виде, по умолчанию используется текстовое представление данных. |
Третий аргумент используется только в том случае, если создается новый файл; он определяет параметры создаваемого файла.
Можно создать поток вывода с помощью стандартного конструктора без аргументов, а позднее выполнить метод open с такими же аргументами, как у предыдущего конструктора:
void open(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Только после того, как поток создан и соединен с определенным файлом (либо с помощью конструктора с аргументами, либо с помощью метода open), можно выполнять вывод. Выводятся данные операцией <<. Кроме того, данные можно вывести с помощью методов write или put:
ostream& write(const char* pch,
int nCount);
ostream& put(char ch);
Метод write выводит указанное количество байтов (nCount), расположенных в памяти, начиная с адреса pch. Метод put выводит один байт.
Для того чтобы переместить текущую позицию, используется метод seekp:
ostream& seekp(streamoff off,
ios::seek_dir dir);
Первый аргумент – целое число, смещение позиции в байтах. Второй аргумент определяет, откуда отсчитывается смещение; он может принимать одно из трех значений:
ios::beg |
смещение от начала файла |
ios::cur |
смещение от текущей позиции |
ios::end |
смещение от конца файла |
Сместив текущую позицию, операции вывода продолжаются с нового места файла.
После завершения вывода можно выполнить метод close, который выводит внутренние буферы в файл и отсоединяет поток от файла. То же самое происходит и при уничтожении объекта.
Класс ifstream, осуществляющий ввод из файлов, работает аналогично. При создании объекта типа ifstream в качестве аргумента конструктора можно задать имя существующего файла:
ifstream(const char* szName, int nMode = ios::in,
int nProt = filebuf::openprot);
Можно воспользоваться стандартным конструктором, а подсоединиться к файлу с помощью метода open.
Чтение из файла производится операцией >> или методами read или get:
istream& read(char* pch, int nCount);
istream& get(char& rch);
Метод read вводит указанное количество байтов (nCount) в память, начиная с адреса pch. Метод get вводит один байт.
Так же, как и для вывода, текущую позицию ввода можно изменить с помощью метода seekp, а по завершении выполнения операций закрыть файл с помощью close или просто уничтожить объект.