Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Общая схема чтения из файла




1)создать потоковый объект

fstream f;

2)открыть для чтения

f.open(“имя”,ios::in|ios::binary);

3)выполнить в цикле чтение из файла в переменную

f.read((char*)&zap,sizeof(zap));

 

 

Открыть файл для изменений (чтения/записи) следует следующим образом:

f.open(“имя”,ios::binary|ios::in|ios::out);

Если указать режим только out без in, то файл усекается до нуля.

Если требуется только писать в файл (в любую позицию), то следует открыть его следующим образом

f.open(“имя”,ios::binary|ios::out|ios::ate);

Если указать только ate без out, то файл не откроется. Если вместо ate указать app, то данные будут писаться всегда в конец файла независимо от seekp().

Таким образом, открытие файла на запись в режиме ios::out приведет к усечению существующего файла до нуля. Для того, чтобы это предотвратить, нужно использовать режим ios::ate. При этом после открытия индекс файла переместится в конец. Затем, если необходимо, перемещение по файлу осуществляет seekp(). Если при открытии был использован режим ios::app, то все данные будут записываться в конец файла, независимо от того, какие команды seekp() выдавались. Однако команда seekg() все же влияет на операцию чтения.

Команда открытия файла выполняется успешно, независимо от того, существует файл или нет. Чтобы предотвратить открытие уже существующего файла, нужно воспользоваться режимом открытия ios::noreplace. Чтобы возникла ошибка, когда файла нет, нужно воспользоваться режимом ios::nocreate.

Как проверить файловый поток на ошибки?

Пусть имеется следующий поток fstream stream. Тогда

if(!stream) //ошибка была

if(stream) //ошибки не было

Более подробную информацию об ошибке можно получить с помощью следующих функций:

if(stream.bad()) //были ошибки

if(stream.eof()) //конец файла

if(stream.good()) //ошибок не было

Если произошла ошибка потока, то дальнейшая работа с ним блокируется. Для продолжения работы необходимо очистить все биты ошибок потока, выполнив функцию clear(), например stream.clear();

Если установлен бит ошибки при чтении за концом файла, то для продолжения работы с файлом следует сбросить бит ios::eofbit и переместить указатель get в начало файла.

stream.clear();stream.seekg(0);

 

Если требуется проверить, открыт ли файл, то следует использовать функцию is_open(), которая возвращает true, если файл открыт, например,

if(!stream.is_open()) //файл не открыт

В заключении перечислим возможные способы открытия файла для операций ввода/вывода.

1.

Создается объект filebuf

filebuf fbuf;

Объект filebuf связывается с устройством файлом, который открывается в требуемом режиме

fbuf.open(“имя”,ios::in);

Создается поток и связывается с filebuf

istream stream(&fbuf);

2.

Создается поток fstream (ifstream, ofstream)

fstream stream;

Открывается файл, который связывается через filebuf с потоком

stream.open(“имя”,ios::in);

3.

Создается объект fstream, одновременно открывается файл, который связывается с потоком

fstream stream(“имя”,ios::in);

4.

Файл открывается функцией ANSI C

FILE* f;

f=fopen(“имя”,”r”);

Создается поток fstream (ifstream, ofstream) и связывается с файлом

fstream stream(*f.fd);


 

7. Новые возможности языка С++

Пространство имен

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

1. Вы работаете в группе разработчиков и ввели в своей программе класс Dog. Кому-то из ваших коллег тоже понадобилось ввести класс Dog. Само по себе это не так уж страшно, поскольку если вы попытаетесь объединить ваши программы, то компилятор обнаружит ошибку дублирования имен. Гораздо хуже, если конфликт имен возникает из-за наличия одинакового имени где-нибудь внутри библиотеки классов, которую вы купили для использования в вашем проекте. Особенно вероятна такая ситуация, когда в одной и той же программе используются библиотеки функций и классов разных производителей. Если библиотеки поставляются без исходных текстов, а только с заголовочными файлами, вы окажетесь в очень затруднительной ситуации.

2. Конфликт второго рода связан с сокрытием переменных. Например, имеется следующий текст:

void main()

{int x;

{int x;

…}

…}

В момент входа во внутренний блок локальная переменная х скрывает внешнюю х из main().

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

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

Этим механизмом и является понятие пространств имен и ключевое слово namespace.

Основная форма объявления пространства имен

namespace имя {

// объявления

}

Все, что определено внутри инструкции namespace, находится внутри области видимости данного пространства имен.

Пример 7.1.1.

namespace MyNameSpace{

int i,k;

void myfunc(int j);

class myclass{

int x;

public:

…};

//определение функций

}

Здесь имена переменных i и k, функции myfunc и класса myclass находятся в области видимости, определенной пространством имен MyNameSpace.

К идентификаторам, объявленным в пространстве имен, внутри этого пространства можно обращаться напрямую. Однако при обращении извне пространства имен к объектам, объявленным внутри этого пространства, следует указывать оператор расширения области видимости

MyNameSpace::i=10;

Если имя часто используется вне своего пространства имен, довольно утомительно писать его каждый раз с квалификатором. Эту проблему можно решить с помощью объявления using.

using имя_ пространства_имен::идентификатор;

Такое объявление делает видимым и, соответственно, доступным в текущем пространстве имен указанный идентификатор.

using MyNameSpace::i;

i=10;

Для того чтобы сделать доступными в текущем пространстве имен все имена из заданного пространства имен, необходимо использовать директиву using.

using namespace имя_ пространства_имен;

using namespace MyNameSpace;

i=10;

k=5;

myclass ob;

Имеется возможность объявить более одного пространства имен с одним и тем же именем. Это позволяет разделить пространство имен на несколько файлов или внутри одного файла.

namespace NS{

int i;

…}

namespace NS{

int j;

...}

Здесь пространство имен NS разделено на две части. Несмотря на это, содержимое каждой части по-прежнему остается в одном и том же пространстве имен NS.

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

Пространство имен может быть объявлено без имени

namespace{

// объявления

}

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

Одна из проблем с namespace состоит в том, что короткие названия пространств имен могут войти в конфликт друг с другом. С другой стороны, весьма неудобно применять длинные имена.

Решение данной проблемы состоит в использовании псевдонимов для namespace.

namespace Lib=Foundation_library_classes;

Перегрузка компонентных функций.

Одним из достоинств пространства имен является возможность вводить в свои программы библиотеки, написанные другими, не заботясь о вероятном совпадении имен.

Пример 7.1.2.

Файл lib.h.

#ifndef LIB_H

#define LIB_H

namespace Other_lib

{

#include<head1.h>

#include< head2.h >

#include< head3.h >

}

namespace LIB=Other_lib;

#endif

 

//использование другой библиотеки

#include<lib.h>

LIB::func();

Для небольших и средних по объему программ маловероятна необходимость создания своих пространств имен. Однако, если вы собираетесь создавать библиотеки функций или классов, предназначенных для многократного использования, или хотите гарантировать своим программам широкую переносимость, вам следует рассмотреть возможность размещения своих кодов внутри некоторого пространства имен. В Microsoft Visual C++ библиотека классов определена в пространстве имен std.

using namespace std;

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...