Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс ПЯВУ 2 сем / Лекции 2 сем / Л№34.Потоковый ввод / Лекция № 32.Потоковый ввод вывод.odt
Скачиваний:
11
Добавлен:
17.04.2015
Размер:
153.09 Кб
Скачать

Void main(int Narg, char *arg[])

{

char path [80] ;

ostrstream(path,sizeof(path)) << arg[0] << '\0';

cout<< "\nПолное имя программы: " << path << endl;

}

Текст этой программы можно взять здесь.

Результат выполнения программы:

Полное имя программы: D:\WWP\TESTPROG\OOP52_1.EXE

Так как операция включения << не переносит в выходной поток признак конца строки '\0', то его пришлось явным образом поместить в выходной поток (тем самым в буфер path[]).

Функция write() применительно к выходному потоку позволяет записывать в него данные без форматирования, т.е. строка записывается вместе с пробельными символами и символом конца строки '\0'. Чтобы продемонстрировать особенности ее применения к безымянным выходным строковым потокам, рассмотрим следующую программу:

//OOР15_2.СРР - запись в безымянный выходной строковый

// поток; копирование строки с использованием функции write().

#include <strstrea.h>

Void main ()

{

char lat[] = "Quod erat demonstrandum!";

char rus[] = " - Что и требовалось доказать!";

char result[60];

ostrstream(result, sizeof (result)) .write (lat, sizeof (lat));

ostrstream(result, sizeof (result) , ios::ate) .write (rus, sizeof (rus));

cout << "\n" << result << endl;

}

Текст этой программы можно взять здесь.

Результат выполнения программы:

Quod erat demonstrandum! - Что и требовалось доказать!

В программе два безымянных потока, каждый из которых "настроен" на символьный массив result[]. При создании первого безымянного потока в качестве параметров конструктора указываются - массив result[] и его размеры, т.е. длина массива в байтах. Функция write() "присоединяется" с помощью операции "точка" непосредственно к конструктору и тем самым вызывается для созданного им безымянного потока. В качестве фактических параметров функции write() используются указатель lat на строку и количество записываемых символов. Так как длина строки меньше длины буфера result, то буфер не заполняется целиком. При создании второго безымянного потока, кроме буфера result и его длины, в конструкторе (в качестве третьего параметра) использован флаг ios::ate, под действием которого поток создается как "дополняемый". Тем самым последующая запись в поток выполняется не с начала потока, а начиная с позиции окончания предыдущей записи '\0'. Именно тут функция write() помещает строку, адресованную указателем rus. Та самым в массиве result[] осуществляется конкатенация строк, что видно из результатов. Из массива result [] вывод в поток cout выполняется до появления символа конца строки ' \0' в массиве result.

Следующая программа иллюстрирует особенности последовательного вывода в строковый поток данных разных типов с помощью операции включения:

//OOР15_3.СРР - вывод в строковый поток операцией <<.

#include <strstrea.h>

void main()

{

char buffer[180];

ostrstream outstring(buffer, sizeof(buffer), ios::out | ios::ate);

outstring << "\nБез явного включения разделителей"

<< " текст в потоке\n\"сливается\":\n ";

outstring << 123456789 << -456 << +1.23456789;

outstring << -0.123456789e+1 << +123.456789e-3 << ends;

cout << "\n" << buffer << endl;

}

Текст этой программы можно взять здесь.

Результат выполнения программы:

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

"сливается":

123456789-4561.23456789-1.23456780.123457

Как показывают результаты, последовательное обращение к строковому потоку приводит к записи "в продолжение", т.е. указатель позиции записи при создании потока устанавливается на его начало, а затем перемещается на длину каждой новой записи. Никаких промежутков или разделителей между выводимыми данными не добавляется. Более того, операция включения в поток << даже не переносит в него нулевой ограничитель конца строки '\0'. Поэтому его нужно добавлять явно, если в дальнейшем требуется использовать буфер потока в качестве строки. Числовая информация, включаемая в поток операцией <<, форматируется. При этом знак + для чисел заменяется пробелом, вещественные числа, заданные в экспоненциальной форме (в научной нотации), переводятся в форму с фиксированной точкой. Выполняется округление дробной части вещественного числа. Перечисленные и проиллюстрированные результатами особенности форматирования могут быть изменены с помощью средств управления форматом как и для стандартных потоков.

На следующем шаге мы рассмотрим двунаправленные строковые потоки.

Основной конструктор строковых потоков, создаваемых как для чтения, так и для записи, имеет следующий формат:

strstream имя_потока (char *buf, int lenBuf, int mode);

где

buf - указатель на участок памяти (буфер потока, обычно символьный массив), для которого создается поток;

lenBuf - длина в байтах участка памяти;

mode - индикатор режима обмена с создаваемым потоком. В качестве индикатора режима обмена используется дизъюнкция флагов, принадлежащих классу ios. Флаги ios::in и ios::out определяют направление обмена. Флаги ios::ate и ios::арр влияют на размещение указателя позиции чтения/записи в буфере и т.д.

В следующей программе с символьным массивом buffer[] связывается двунаправленный поток string. Затем последовательно выполняются операции записи в поток и чтения из потока.

//OOР16_1.СРР - ввод и вывод для двунаправленного строкового потока.

#include <strstrea.h>