|
Программирование >> Структурное программирование
Типичная ошибка программирования 14.2 Использование неверного объекта класса ofstream при ссылке на файл. Объект класса ofstream может быть создан без открытия какого-то файла - в этом случае файл может быть связан с объектом позднее. Например, объявление ofstream outClientFile; . создает объект outClientFile класса ofstream. Функция-элемент open класса ofstream открывает файл и связывает его с существующим объектом класса ofstream, как показано ниже: outlientFile.open( clients.dat , ios:lout); Типичная ошибка программирования 14.3 Не открывается файл перед попыткой сослаться на него в программе. После создания объекта класса ofstream и попытки открыть его программа проверяет, была ли операция открытия файла успешной. Фрагмент программы if (!outClientFile) { cerr Файл не может быть открыт << endl; exit (1) ; использует перегруженную функцию-операцию operator! - элемент класса ios, для определения того, успешно ли открылся файл. Условие возвращает ненулевое значение (true), если при выполнении операции open для потока устанавливаются или failbit или badbit. Некоторые возможные ошибки являются следствием попытки открыть для чтения несуществующий файл, попытки открыть файл для чтения без разрешения или открытия файла для записи, когда на диске нет свободного места. Когда условие указывает, что попытка открытия файла была безуспешной, выводится сообщение Файл не может быть открыт и вызывается функция exit для завершения программы. Аргумент функции exit возвращается среде окружения, из которой программа была вызвана. Аргумент О показывает, что программа завершается нормально, а любое другое значение, указывает среде окружения, что программа прекратила выполнение из-за ошибки. Значение, возвращаемое функцией exit, используется средой окружения (чаще всего операционной системой) для соответствующей реакции на ошибку. Другая перегруженная функция-операция operator void* - элемент класса ios, превращает поток в указатель, так что можно проверить, является ли он О (нулевым указатель), или имеет ненулевое значение (любое другое значение указателя). Если для потока устанавливаются failbit или badbit (см. главу 11), то возвращается О (false). Условие в заголовке оператора while автоматически вызывает функцию-элемент operator void*: while (cin account name balance)
Рис. 14.6. Комбинации клавиш для различных популярных операционных систем Это условие истинно, пока для cin не устанавливаются ни failbit, ни badbit. Ввод маркера конца файла устанавливает failbit для cin. Функция operator void* может быть использована для проверки конца файла в объекте ввода вместо явного вызова функции-элемента eof. Если файл открылся успешно, то программа начинает обрабатывать данные. Следующий оператор запрашивает пользователя о вводе различных полей каждой записи или информацию о конце файла, если ввод данных завершен: cout << Введите счет, имя и баланс. << endl << Введите EOF - для окончания ввода. << endl << ? ; Рис. 14.6 дает список комбинаций клавиш для ввода признака конца файла в различных системах. Строка while (cin account name balance) вводит каждый набор данных и определяет, не введен ли признак конца файла. Когда достигнут конец файла или вводятся неверные данные, операция извлечь из потока возвращает О (обычно операция извлечь из потока возвращает cin) и оператор while завершает свою работу. Пользователь должен вводить признак конца файла, чтобы сообщить программе о том, что ввод необходимых данных завершен. Маркер конца файла устанавливается, когда пользователь вводит ключевую комбинацию конца файла. Оператор while продолжает выполнение цикла до тех пор, пока не будет введен маркер конца файла. Оператор outClientFile account name balance endl; записывает набор данных в файл clients.dat , используя операцию поместить в поток и объект outClientFile, связанный с файлом в начале программы. Может быть проведена выборка данных с помощью программы, предназначенной для чтения файла (см. раздел 14.5). Заметим, что файл, приведенный на рис. 14.4, является текстовым файлом. Он может быть прочитан с помощью любого текстового редактора. Как только вводится признак конца файла, функция main завершается. Это приводит к тому, что объект outClientFile уничтожается вызовом его деструктора, который закрывает файл clients.dat. Объект ofstream может быть явным образом закрыт программистом с помощью функции-элемента close: outClientFile.close(); Совет по повышению эффективности 14.1 Закрывайте явным образом каждый файл, как только станет понятным, что программа не будет обращаться к этому файлу снова. Это поможет сократить используемые ресурсы, которые программа продолжает потреблять длительное время после того, когда ей уже не надо обращаться к данному файлу. Этот прием делает программу также более ясной. В примере выполнения программы на рис. 14.4 пользователь вводит сведения по пяти счетам и затем сообщает, что ввод данных завершен, с помощью ввода признака конца файла (Z появляется на экранах компьютеров, совместимых с IBM PC). Для проверки того, что файл создан успешно, в следующем разделе мы создадим программу чтения файла и печати его содержимого. 14.5. Чтение данных из файла последовательного доступа Данные сохраняются в файлах так, чтобы их можно было найти и обработать, когда в этом возникнет необходимость. В предыдущем разделе было показано, как создать файл последовательного доступа. В этом разделе обсудим, как последовательно считывать данные из файла. Программа, приведенная на рис. 14.7, считывает записи из файла clients.dat , созданного программой на рис. 14.4, и печатает содержимое записей. Файлы открываются для ввода путем создания объекта класса ifstream. Объекту передаются два аргумента - имя файла и режим открытия файла. Объявление ifstream inClientFile( clients.dat , ios::in); создает объект inClientFile класса ifstream и связывает с ним файл clients.dat, то есть открывает его для ввода. Аргументы в круглых скобках передаются конструктору класса ifstream, который открывает файл и устанавливает с ним линию связи . Объекты класса ifstream открываются для ввода по умолчанию, так что для открытия файла clients.dat на ввод может быть использован оператор ifstream inClientFile{ clients.dat ); Так же, как и в случае объекта класса ofstream, объект класса istream может быть создан без открытия кокого-то файла, а файл может быть связан с ним позднее. Хороший стиль программирования 14.1 Открывайте файл для только для ввода (используя ios::in), если содержимое файла не должно быть модифицировано. Это способствует предотвращению непреднамеренной модификации содержимого файла. Это пример принципа наименьших привилегий. Программа использует условие ! inClientFile для определения того, успешно ли открыт файл, до попытки осуществить выборку из этого файла. Строка while (inClientFile account name >> balance)
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |