Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ввод-вывод.doc
Скачиваний:
8
Добавлен:
18.04.2015
Размер:
273.92 Кб
Скачать

Функции чтения

Если надо прочитать строку символов, содержащую пробелы, то с помощью операции это сделать не просто – каждое чтение выполняется до пробела, а ведущие левые пробелы игнорируются.

Это легко можно сделать с помощью функций класса istream – функций бесформатного двоичного чтения.

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

Двоичное чтение – это чтение любой информации как последовательность байт. Данные читаются без преобразования.

Напр., если во входном потоке находится представление вещественного числа 1.7E-2, то оно будет воспринято как последовательность из шести байт, и читать эту последовательность с помощью функций двоичного ввода можно только в символьный массив из 7 символов.

1) istream & get (signed char* array, int n , char=’\n’);

2) istream & get (unsigned char* array, int n , char=’\n’) ;

Функции извлекают последовательность n-1 байтов из потока и переносят их в символьный массив (буфер), задаваемый первым параметром. Затем в массив помещается концевой символ ‘\0’.

Если раньше встретился ограничительный символ – третий параметр, то чтение прекращается, сам ограничитель не извлекается из потока, в формируемую строку не переносится, а помещается концевой символ ‘\0’.

Таким образом, массив должен иметь длину не менее n символов. Если встретился EOF, то он воспринимается как ограничительный символ.

3) istream & get (signed char & c);

4) istream & get (unsigned char & c);

Извлекают один символ из потока и присваивают его параметру

5) int get ( ) ;– Возвращает код извлеченного символа, если поток пуст

возвращает код конца файла.

6) istream & getline (signed char* array, int n , char=’\n’);

7) istream & getline (unsigned char* array, int n , char=’\n’);

Аналогичны первым двум функциям, но удаляется из входного потока и символ ограничитель.

8) int peek( ) ;

Возвращает код очередного символа потока (или EOF , если поток пуст)

char ch; while(cin.peek() != ‘\n’) { cin.get(ch) ; cout.put (ch);}

9) istream & putback(char) ;– помещает символ в поток , он и будет

следующим читаемым символом

10) istream & ignore (int n=1 , int m = EOF) ; - позволяет проигнорировать

n символов потока , m -символ ограничитель.

11) istream & read (signed char* array, int n );

12) istream & read (unsigned char* array, int n );

Считывают из потока n символов в массив array

13) istream & seekg ( long pos) ; -устанавливает позицию чтения

14) istream & seekg ( long pos, seek_dir dir) ;

где параметр dir принимает значение из перечисления

enum seek_dir {ios :: beg, ios::cur, ios::end}

pos - относительная величена смещения ( в байтах) указателя во

входном потоке, относительно трех ориентиров.

15) ostream & seekp( long pos) ; - устанавливает позицию записи в поток

16) ostream & seekp( long pos, ios :: beg )

15) long tellg( ); - определяет текущую позицию чтения

16) long tellp( ); определяет текущую позицию записи

Строковые потоки ( обмены в оперативной памяти)

Классы istrstream, ostrstream, strstream предназначены для создания потоков, связанных с участками основной памяти. Такие участки определяются часто как символьные массивы. Объекты (потоки) названных классов называют строковыми потоками.

Определение :

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

<Имя класса> < имя потока(объекта)> ( параметры конструктора)

Входные строковые потоки (из которых читают) создаются с помощью вызова следующего конструктора

istrstream in (char *str );

параметр str указывает на существующий участок памяти

Пример: char buf [80] ;

istrstream in (buf);

Входной строковый поток in связан с участком памяти, выделенным под массив buf. Теперь используя поток in и операцию >> можно из массива buf считывать значения, в какие либо данные.

Пример:

#include <strstrea.h>

void main()

// выделяем область памяти для обмена

{char*stroka=”1436.7 Auda!”

istrstream instr ( stroka );

char mas[10];

float b;

instr>> b>> mas; //распаковка строки

cout << b << “ “ << mas << endl;

}

Операция >> извлекает информацию от первого не пробельного символа до первого пробела. Чтобы считывать с пробелами, надо использовать функции get( ) и getline ( ). С помощью этих функций при использовании строковых потоков, можно организовать копирование строк.

char * stroka = “ 1917 \t – год революции “

istrstream instr ( stroka );

char array [80];

instr.getline ( array, sizeof(array) , ‘\0’);

cout<<array;…

1917 - год революции

Безымянные входные потоки – это создание безымянного объекта

Вызывается конструктор без имени

char* stroka = “ … “

char array [50];

istrstream ( stroka)>>array; // введет до первого пробела

… istrstream ( stroka).getline(array , 50 , ‘\0’)// введет всю строку опять с ее

//начала

Выходные строковые потоки ( связывается с участком ОП для вывода данных) создается вызовом конструктора с параметрами

ostrstream outstr ( char*str, int n , int mod )

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

ios:: out

  • строковый поток создается для вывода, запись информации ведется с начала строки, выбирается по умолчанию.

ios::ate ( ios :: app)

  • позиция записи в месте нахождения символа ‘\0’( продолжение записи)

Пример безымянного выходного строкового потока

#include < strstrea.h>

void main( )

{ char buf [80];

char al [ ]=«\nБез включения разделителей «

char ol [ ] =« текст\n\»сливается\» .\n»

ostrstream ( buf, sizeof(buf) ).write(al , sizeof(al));

ostrstream ( buf, sizeof(buf) , ios :: ate).write(ol , sizeof(ol));

cout << buf<<endl;

Без включения разделителей текст

«сливается» .

Функция write( ) вызывается для безымянного потока. Запись идет в массив buf[ ]. Вывод в строку с помощью write идет подряд и без форматирования. Строка al записывается в buf[ ] вместе с пробелами и признаками конца строки. Байтовый ноль в строку переносится. Т.к. длина строки меньше длины буфера, то буфер не заполнится целиком. При создании второго безымянного потока с помощью конструктора , в качестве третьего параметра указывается флаг ios :: ate, что означает, что поток открыт для дополнения. Последняя запись в поток осуществляется, начиная с позиции символа ‘\0’ предыдущей записи, туда адресуется строка ol. Т.е. в buf[ ] запишется результат конкатенации строк, который и выведется на экран последним оператором.

Используем для вывода операцию включения в поток <<.

Будем использовать для разнообразия именованный поток .

…{

ostrstream outstr( stroka, sizeof(stroka), ios::out | ios::ate ) // мода для до-

//полнения строки

outstr<<”\nБез включения разделителей»

<<« текст\n\»сливается\» .\n»

<< 12345<<-4.67<<+1.456<<ends;…

cout<< stroka;}

Без включения разделителей текст

«сливается» .

12345-4.67 1.456

При создании потока (для дополнения) указатель потока устанавливается на начало потока, а затем перемещается на длину каждой новой записи без промежутков. При использовании операции включения в поток << даже

байтовый ноль ’\0’ в строку-буфер не переносится и его надо добавлять явно, если надо использовать буфер потока(stroka) в качестве строки. Числовая информация, включаемая в поток, форматируется, средства изменения форматов были рассмотрены выше.

Знак “+” заменяется пробелом.

Двунаправленные потоки

Конструктор строковых потоков для чтения и для записи имеет вид:

strstream outstr ( char*buf, int n , int mod )

buf – указатель на участок памяти ( буфер потока);

n – размер в байтах участка памяти

Третий параметр – это дизъюнкция флагов

ios:: in ios::out – определяет направление потока

ios::ate ios app –влияют на размещение указателя позиции чтения или записи в буфере.

Пример 1:

#include <strstrea.h>

void main ()

{ char buf [100];

char s [80];

// объявляем двунаправленный строковый поток, связанный с массивом buf[]

strstream iostr ( buf, sizeof(buf) , ios:in |ios::out );

iostr<< “Строковый поток связан с участком ОП.” <<ends;

//позиция записи сместилась в конец потока, позиция чтения на начале //потока

iostr>>s; cout<<’\n’<< s; // читает до пробела

iostr>>s; cout<<’\n’<< s; // читает следующее слово

// установим позицию чтения на начало потока и прочитаем весь буфер

iostr.seekg ( 0L, ios::beg );

iostr.getline( s, sizeof(s), ‘\0’ ); // копирование из буфера потока buf в s

cout<<’\n’<<s;

Результат:

Строковый

Поток

Строковый поток связан с участком ОП.

Пример 2:

#include <strstrea.h>

#include<conio.h>

char link[200]; // массив для буфера

strstream obmen ( link, sizeof(link) , ios::in |ios::out );// определение

//двунаправленного потока

struct elem { int nk, nl ; float nz;}; // определена структура

strstream &operator >> (strstream & in , elem & el)// перегрузка операции

{in >> el.nk >> el. nl >>el.nz; return in;} //ввода

ostream &operator << (ostream & out , elem & el)// перегрузка операции

{ out << el.nk <<"\t " << el. nl << "\t " <<el.nz<<"\n"; return out;}

// вывода

// функция чтения из потока

void res(void)

{ elem elz; //объявлена структура

int num;

obmen >> num;

cout << num<<'\n';

for(int i=0 ; i< num; i++) { obmen >> elz; cout<<elz;}

}

void main()

{clrscr();

// char buffer [180];

elem arel[5]={{ 1, 2 ,3.45}, {3, 4 , 4.56},

{5, 6, 5.7}, {7, 8, 7.7 },

{ 9, 10, 7.7}} ;

int k=5;

obmen << k<<" ";

for(int i=0 ; i< 5; i++)

obmen << arel[i];

obmen<<ends;

res ( );

}

Результат:

5

1 2 3.45

3 4 4.56

Перегрузка операции включения << для базового потока класса ostream наследуется производным классом strstream для строковых потоков. Поэтому дополнительно для строковых потоков перегружать эту операцию не надо.