Вывод ланных типа char
ostream _FAR & _RTLENTRY operator<< ( char);
ostream _FAR & _RTLENTRY operator<< ( signed char);
ostream _FAR & _RTLENTRY operator<< (unsigned char);
Вывод числовых данных с преобразованием во внешнее представление
ostream _FAR & _RTLENTRY operator<< (short);
ostream _FAR & _RTLENTRY operator<< (unsigned short);
ostream _FAR & _RTLENTRY operator<< (int);
ostream _FAR & _RTLENTRY operator<< (unsigned int);
ostream _FAR & _RTLENTRY operator<< (long);
ostream _FAR & _RTLENTRY operator<< (unsigned long);
ostream _FAR & _RTLENTRY operator<< (float);
ostream _FAR & _RTLENTRY operator<< (double);
ostream _FAR & _RTLENTRY operator<< (long double);
Вывод строк, оканчивающихся нулевым байтом
ostream _FAR & _RTLENTRY operator<< (const char _FAR *);
ostream _FAR & _RTLENTRY operator<< (const signed char _FAR*);
ostream _FAR & _RTLENTRY operator<< (const unsigned char _FAR*);
Вывод значения указателя в символьном формате
ostream _FAR & _RTLENTRY operator<< (void _FAR *);
Извлечение данных их объекта streambuf и вставка в тот же ostream
ostream _FAR & _RTLENTRY operator<< (streambuf _FAR *);
Вывод значений манипуляторов
ostream _FAR & _RTLENTRY operator<<
(ostream _FAR & (_RTLENTRY *_f)(ostream _FAR &));
(ios _FAR & (_RTLENTRY *_f)(ios _FAR &));
Имеется также класс iostream, производный от класса ios и объединяющий возможности классов istream и ostream.
Для рассмотренных выше классов отсутствуют конструкторы копирования и операция присваивания, точнее, они объявлены, но не определены. Для тех случаев, когда конструктор копирования и операция присваивания необходимы, предусмотрены классы istream_withassign, ostream_withassign и iostream_withassign. Как экземпляры объектов этих классов всегда объявляется объект cin (экземпляр istream_withassign), обычно предназначенный для ввода с клавиатуры, и объекты cout, cerr и clog (экземпляры ostream_withassign), обычно предназначенные для вывода на экран.
Ввод-вывод для дисковых файлов обепечивается классами, описания которых содержатся в файле fstream.h.
Класс filebuf, производный от streambuf, предназначен для добавления в streambuf дополнительных средств управления буфером ввода-вывода.
Класс fstreambase, производный от класса ios, служит базой для остальных классов, обеспечивающих файловый ввод-вывод, в нем определены методы:
void _RTLENTRY open(const char _FAR *, int, int = filebuf::openprot);
void _RTLENTRY attach(int);
void _RTLENTRY close();
void _RTLENTRY setbuf(char _FAR *, int);
Назначение этих методов очевидным образом следует из их названий.
Для непосредственной работы с файлами служат классы ifstream, ofstream и fstream, базой для них служат классы fstreambase и, соответственно, istream, ostream и iostream.
Для вывода данных в дисковый файл в программе должна присутствовать директива препроцессора
#include <fstream.h>
Прежде чем выводить данные необходимо создать объект типа ofstream, для которого имеется несколько конструкторов:
_RTLENTRY ofstream(); // Пустой объект, без привязки к файлу
// С привязкой к файлу, полное имя которого задается первым аргументом:
_RTLENTRY ofstream(const char _FAR *, int = ios::out,
int = filebuf::openprot);
// С привязкой к ранее открытому файлу, заданному своим дескриптором
_RTLENTRY ofstream(int);
// То же, что и предыдущий вариант, но задается новый буфер вывода
_RTLENTRY ofstream(int __f, char _FAR *, int);
Наиболее часто оказывается полезным второй вариант конструктора, в котором указывается только первый параметр - полное имя файла. Этот конструктор создает объект типа ofstream, открывает указанный файл и присоединяет его к потоку вывода.
Собственно операции вывода реализуются вызовом методов put, write или с использованием переопределенных операций <<.
Аналогичным способом обеспечивается и ввод из файла: создается объект типа ifstream и для ввода применяются методы get, read или переопределенные операции >>.
Для типа ifstream имеется набор аналогичных конструкторов:
_RTLENTRY ifstream();
_RTLENTRY ifstream(const char _FAR *,int = ios::in,
_RTLENTRY ifstream(int);
_RTLENTRY ifstream(int __f, char _FAR *, int);
В качестве примера рассмотрим программу, копирующую данные из одного файла в другой.
#include <process.h> // Для вызова exit
int main ( int argc, char* argv [ ] )
{ char ch;
if ( argc != 3 ) // Проверка числа аргументов
{ cerr << “ Вызов dcopy файл1 файл2 \n” ; exit ( 1 ) ; }
ifstream source( argv [ 1 ] ) ; // Входной поток
if ( ! source )
{ cerr << “ Нельзя открыть входной файл “ << argv [ 1 ] ;
exit ( 1 ); }
ofstream dest ( argv [2 ] ) ;
if ( ! dest )
{ cerr << “ Нельзя открыть выходной файл “ << argv [ 2 ] ;
while ((ch = source.get ( ) ) != EOF )
dest.put( ch );
close ( source ); close ( dest );
return 0 ;
}
Организация вывода данных определенных программистом объектных типов, в общем случае зависит от предполагаемого дальнейшего использования этих данных. Могут сохраняться в файле все компоненты данные, или только часть из них, может применяться форматированный или бесформатный вывод. Часто возникает необходимость сохранить объектные данные в файле для последующего их восстановления в той же или другой программе.
Для вывода объекта в файл в определение класса может быть включена функция-компонента с параметром ссылкой на объект типа ostream. Часто такой функции назначают имя print или printon. Более изящным считается переопределение оператора << для вывода объектного данного. Если компоненты-данные объекта имеют уровень доступа protected или private, а оператор << не является компонентой класса, его следует объявить как friend-метод.
Пусть, например, в программе определен класс complex:
class complex
{ double re, im ;
public:
complex (double r =0, double i =0 ): re ( r ), im ( i )
{ } // конструктор
double real ( ) {return ( re ); }
double image ( ) { return ( im ); }
/* другие методы */
Тогда для форматированного вывода комплексного числа в формате ( вещественная часть, мнимая часть ) можно так переопределить операцию << :
ostream& operator << ( ostream& s, complex c )
{ int old_precision = s.precision ( 4 ); // установка числа дробных цифр
s << “(“ << c.real( ) <<
“, “ << c.image( ) << “)” ;
s.precision ( old_precision ) ; // восстановление числа дробных цифр
return ( s );
В данном случае в переопределении << нет обращения к личным переменным класса Complex. Если не использовать методы real и image, переопределение << нужно было бы включить в описание класса Complex с описателем friend.
Ввод объектного данного из файла или стандартного потока организуется аналогично: либо в определение класса включается функция-компонента для инициализации компонент данных их входного потока, либо переопределяется операция >> для ввода компонент-данных из потока. В некоторых случаях оказывается более удобным включить в описание класса дополнительный конструктор с параметром-ссылкой на объект типа istream, при этом все базовые классы должны иметь аналогичные конструкторы.
Пусть в описание класса Complex включена переопределенная операция >>:
complex (double r =0,double i=0 ): re( r ), im( i ) { } // конструктор
friend istream& operator >> ( istream& , Complex& );
Если предположить, что комплексные числа поступают из потока либо в виде вещественного числа, возможно заключенного
в скобки, либо в виде пары чисел, разделенных запятой и заключенной в скобки,
то переопределяемую операцию ввода можно описать следующим образом:
istream& operator >> ( istream& s, Complex& c )
{ double re_n = 0, im_n = 0;
char ch = 0;
s >> ch ;
if ( ch == ‘(‘ )
{ s >> re_n >> ch ;
if ( ch == ‘,’ ) s >> im_n >> ch;
if ( ch != ‘)’) s.clear ( ios::failbit ); //Установка признака ошибки
else { s.putback ( ch ); s >> re_n ; }
if ( s ) { c.re = re_n; c.im = im_n; } // Если не было ошибки
Рассмотренные выше примеры сохранения объектов
в потоке и восстановления их из потока иллюстрируют наиболее простые варианты
этих операций. Проблема сохранения объектов в потоке существенно усложняется,
когда требуется сохранять в одном потоке объекты разных типов, когда между
объектами разных типов имеются ссылки и некоторый объект содержит указатель
на объект другого типа, причем на один и тот же объект могут ссылаться
несколько других объектов. В этой ситуации требуется для каждого сохраняемого
в потоке объекта заносить в поток идентификатор типа объекта, гарантировать,
что каждый объект, на который имеются ссылки из других объектов, будет
помещен в поток только один раз. Средства для разрешения этих проблем имеются
в библиотеке классов-контейнеров classlib, содержащей
файл objstrm.h с определениями необходимых
классов и макросов.
1. Составить функцию для подсчета числа серий положительных, отрицательных чисел и нулей длиной не менее К в одномерном массиве целых чисел. Серией называется последовательность элементов массива, принадлежащих одному классу:
Страницы: 1, 2, 3, 4, 5, 6, 7