- •( Stream – поток, I - input , o – output)
- •Иерархия потоковых классов (одна ветвь)
- •Стандартные потоки ввода – вывода
- •1) Для целых чисел, 2) для вещественных чисел и 3) для строк
- •Компонентные функции класса ios для форматирования
- •Манипуляторы с параметрами ( определены в файле iomanip.H )
- •Ввод-вывод для типов, определенных пользователем
- •Функции чтения
- •Работа с файлами
- •Ввод-вывод нижнего уровня
- •Текстовой и бинарный файлы
- •Открытие и закрытие файлов
- •Чтение и запись данных
- •Int fd ; // дескриптор файла
Функции чтения
Если надо прочитать строку символов, содержащую пробелы, то с помощью операции это сделать не просто – каждое чтение выполняется до пробела, а ведущие левые пробелы игнорируются.
Это легко можно сделать с помощью функций класса 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 для строковых потоков. Поэтому дополнительно для строковых потоков перегружать эту операцию не надо.