|
Практический пример. Показ содержимого директории.Реализуем в данном примере возможность показа содержимого директории. Данная программа при запуске показывает содержимое текущей директории. Для перехода в другую директорию нужно ввести команду cd.Примеры: cd C:\\MyPictures ( покажет содержимое каталога C:\\MyPictures); cd C:\Games\3DKitchen ( покажет содержимое каталога C:Games3DKitchen);cd .. ( покажет содержимое родительского каталога и перейдет в него); cd ( покажет содержимое текущего каталога);cd . ( покажет содержимое текущего каталога);. Для выхода из программы нужно ввести exit . Для перехода в корневой каталог необходимо ввести команду root. (Все вышеперечисленные команды регистронезависимы).. Ввод-вывод в языке С++.Средства ввода/вывода не входят непосредственно в язык С++, поэтому библиотека ввода/вывода становится одной из самых незаменимых при программировании на С++. На протяжении многих уроков, используя директиву препроцессора include мы подключали к нашим программам заголовочный файл iostream.h. Его назначение - связать компилируемую программу с одной из основных частей бибилотеки ввода/вывода, построенной на основе механизма классов. Потоки ввода-вывода.Описанные в файле iostream.h средства ввода-вывода обеспечивают программиста механизмами для извлечения данных из потоков и для включения (помещения) данных в потоки. При обмене с потоком часто используется вспомогательный участок основной памяти - буфер потока. В буфер потока помещаются выводимые программой данные перед тем, как они будут переданы внешнему устройству. При вводе данных они вначале помещаются в буфер и только затем передаются в область памяти выполняемой программы. Использование буфера повышает скорость передачи данных, т.к. реальные пересылки осуществляются только тогда, когда буфер уже заполнен (при выводе) или пуст (при вводе). Используемые в программе потоки логически делятся на входные, из которых читается информация, выходные, в которые вводятся данные и двунаправленные, допускающие как чтение, так и запись. Чтобы можно было использовать потоковые классы, а соответственно, их данные и методы необходимо включить в программу нужный заголовочный файл:
Предопределенные потоки.Библиотека ввода-вывода имеет 4 предопределенных объекта-потока, ассоциированных со стандартным вводом и выводом:
Каждый раз при включении в программу файла iostream.h происходит формирование объектов cin, cout, cerr и clog, т.е. создаются соответствующие стандартные потоки, и программисту становятся доступными связанные с ними средства ввода-вывода. Операции помещения в поток и извлечения из потока.Библиотека потоков С++ предусматривает два основных класса для ввода и вывода: istream и ostream. Класс ostream использует для вывода переопределенную операцию левого сдвига (<<), которую называют операцией помещения в поток. Класс istream использует для ввода переопределенную операцию правого сдвига (>>), которую называют операцией извлечения из потока. Операции помещения и извлечения допускают сцепленные вызовы, т.к. возвращают значение ссылки на поток. Классы istream и ostream перегружают операции помещения и извлечения для всех встроенных типов данных. Такая перегрузка позволяет использовать единый синтаксис для ввода и вывода символов, строк, целых и вещественных чисел. Операции помещения/извлечения можно легко распространить на пользовательские типы данных. Для этого надо определить две функции со следующими заголовками (вспоминайте материал предыдущих занятий, тема "Перегрузка операторов"): istream& operator >> (istream&, имя_типа&);Определяя операции помещения/извлечения для классов, их обычно делают дружественными, чтобы обеспечить доступ к закрытым элементам данных класса. Файловый ввод-вывод с применением потоков.В программах, которые мы писали до сих пор, вся информация, вводимая в процессе работы программы, терялась по окончании работы. Такие программы используются редко. Обычно одна и та же информация используется многократно в течении длительного времени. Для многократного использования информации ее записывают на диск в виде файла. Файлом можно назвать объект с именем, доступ к которому поддерживает (обеспечивает) операционная система. Поддержка операционной системы состоит в том, что в ней имеются средства:
Логически последовательный файл можно представить как именованную цепочку байтов, имеющую начало и конец. С помощью средств библиотеки можно осуществить следующие процедуры: создание файла, создание потока, открытие файла, "присоединение" файла к потоку, обмен с файлом с помощью потока, "отсоединение" потока от файла, закрытие файла, уничтожение файла. Кратко рассмотрим наиболее простые и удобные механизмы указанных действий. Как уже отмечалось, библиотека потоков содержит три класса, предназначенных для ввода и вывода в файлы:
Конструкторы файловых потоков.Если Вы посмотрите, как описаны классы ifstream, ofstream, fstream, обратите внимание на перегруженные конструкторы (для каждого из файловых классов предусмотрено 4 конструктора), например, наиболее используемые из них: имя_класса ();Например, для класса fstream: fstream() - создает поток, не открывая файла; Например, определение файловых потоков, используя конструкторы по умолчанию: ofstream outf; // определяется выходной файловый потокПараметр omode - дизъюнкция флагов, определяющих режим работы с откываемым файлом (например, только запись). Флаги определяются в файле ios.h (см. перечислимая константа open_mode). enum open_mode {
Для файла ifstream по умолчанию параметр omode = ios::in,
для класса ofstream по умолчанию параметр omode = ios::out.
Функции для открытия и закрытия файлов.Создание файлового потока (объекта соответствующего класса) связывает имя потока с выделяемым для него буфером и инициализирует переменные состояния потока. Так как файловые классы являются производными от классов ostream, istream, stream, то они поддерживают форматированный и бесформатный обмен с файлами. Но прежде чем выполнить обмен, необходимо открыть соответствующий файл и связать его с файловым потоком. "Присоединить" файловый поток к конкретному файлу можно с помощью компонентной функции open(). Функция open() унаследована каждым из файловых классов ofstream, ifstream, fstream от класса fstreambase. Формат функции (такой же, как у второго конструктора fstream): void open(const char *fileName, int mode = значение_по_умолчанию, fileName - имя уже существующего или создаваемого заново файла. Это строка, которая задает полное или сокращенное имя файла в формате, определенном операционной системой. Как обычно вызов функции open() осуществляется с помощью уточненного имени имя_объекта_класса.вызов_принадлежащей_классу_функцииНапример, outf.open("d:\temp\file1.txt");
Чтобы проверить, удачно ли завершена функция open(), используется
перегруженная операция !. Если ошибок не было, то выражение
!имя_потока имеет нулевое значение, в противном случае -
значение, отличное от нуля.
// ...Для потоков класса fstream второй параметр должен быть задан явно, так как иначе неясно в каком направлении предполагается выполнять обмен с потоком. Все файловые классы унаследовали от базовых классов функцию close(), которая очищает буфер потока, отсоединяет поток от файла и закрывает файл. Функцию close() необходимо явно вызывать при изменении режимов работы работы с файловым потоком. Автоматически эта функция вызывается только при завершении программы. Функции для обмена с потоками.Кроме операций помещения в поток и извлечения из потока, в классах библиотеки ввода-вывода есть весьма полезные функции, обеспечивающие программиста дополнительными средствами для обмена с потоками. Бесформатный ввод и вывод. Бесформатный ввод и вывод обеспечивают наибольшую скорость обмена информацией. Для него предназначены следующие функции. Чтение блока символов:len - максимальное число символов, которые должны быть извлечены из потока в буфер buf. Истинное количество извлеченных символов возвращает функция gcount(). Запись блока символов:n - число символов, считая ноль-символ, которые должны быть помещены в поток из буфера buf. Извлечение одного символа из потока: Помещение одного символа в поток: Извлечение строки из потока:Символы извлекаются и помещаются в буфер пока не будет найден символ-ограничитель, или не будет прочитано n символов, или не встретится конец файла. Ограничитель из потока не извлекается и в буфер не помещается. В противоположность функция getline, которая выполняет то же, что и get, но ограничитель извлекается из потока (в буфер не заносится). istream& istream::getline(unsigned char *buf, int n, char c = 'n');
Пропуск символов при вводе.извлекает символы из потока, пока не встретится ограничитель d или пока не извлечет n символов. Проверка счетчика извлечения.- возвращает число символов, извлеченных последней функцией бесформатного ввода. "Заглядывание" вперед.- позволяет "взглянуть" на очередной символ входного потока - возвращает код следующего символа потока (или EOF, если поток пуст), но оставляет этот символ в потоке. При необходимости этот символ можно извлечь из потока с помощью других средств библиотеки. Возврат символа в поток.- не извлекает ничего из потока, а помещает в него символ cc, который становится текущим и будет следующим извлекаемым из потока символом. Позиционирование потока.- устанавливает позицию чтения из потока в положение, определяемое значением параметра. istream& istream::seekg(long off, ios::seek_dir dir);- выполняет перемещение позиции чтения вдоль потока в направлении, опеределенном параметром dir, который принимает значение из перечисления enum seek_dir {beg, cur, end};. Относительная величина перемещения ( в байтах) определяется значением параметра long off. Если направление определено как beg, то смещение от начала потока; cur - от текущей позиции; end - от конца потока. ostream& ostream::seekp(long pos);- устанавливает абсолютную позицию записи в поток. ostream& ostream::seekp(long off, ios::seek_dir dir);- аналогична функции seekg(), но принадлежит классу ostream и выполняет относительное перемещение записи в поток. Определение текущей позиции потока.- определяет текущую позицию чтения из потока. long ostream::tellp();- определяет текущую позицию записи в поток. <<<<Назад [Содержание] |
|
