Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции C++.doc
Скачиваний:
7
Добавлен:
01.05.2025
Размер:
1.44 Mб
Скачать

8.6 Произвольный доступ в массив

Важно помнить, что все обычные операции ввода/вывода сохраняют свое значение для ввода/вывода в массивы. Сюда относится также произвольный доступ с использованием функций seekg() и seekp(). В качестве примера следующая программа получает восьмой символ в iostr и выводит его. (Выводится символ h.)

#include <strstrea.h>

#include <iostream.h>

int main()

{

char iostr[80];

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

char ch;

i << "abcdefghijklmnopqrstuvwxyz";

i.seekg(7, ios::beg);

i >> ch;

cout << "Character at 7: " << ch << endl;

return 0;

}

Можно проводить поиск где угодно внутри массива, но нельзя осуществлять поиск за его пре­делами.

Также можно использовать функции tellg() и tellp().

8.7 Использование динамических массивов

В начале этой главы при связывании потока с массивом для вывода данных этот массив и его раз­мер передавались конструктору класса ostrstream. Такой подход работает до тех пор, пока изве­стно максимальное количество символов, которое потребуется вывести в массив. Что же делать, когда заранее неизвестно, насколько большой массив понадобится в дальнейшем? Решением этой проблемы служит вторая форма конструктора ostrtream, показанная ниже:

ostrtream();

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

Для доступа к динамически выделяемому массиву следует использовать функцию str(). Она имеет следующий прототип:

char* str();

Эта функция «замораживает» массив и возвращает указатель на него. Как только массив замо­рожен, он не может снова использоваться для вывода данных. Поэтому не следует замораживать массив, пока продолжается запись в него символов.

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

#include <strstrea.h>

#include <iostream.h>

int main()

{

char *p;

ostrstream outs; // динамическое размещение массива

outs << "I like C++ ";

outs << -10 << hex << " ";

outs.setf(ios::showbase);

outs << 100 << ends;

p = outs.str(); /* заморозка динамического буфера и возврат указателя на него */

cout << р;

delete p; //освобождение динамического буфера, созданного ostrstream()

return 0;

}

Как показывает эта программа, если заморозить массив, то придется самостоятельно освободить память при выходе из функции или программы. Однако если массив не заморожен, память бу­дет освобождена автоматически при уничтожении потока ввода/вывода.

Можно также использовать динамические массивы с классом strstream, позволяющим как вво­дить, так и выводить данные в массив.

8.8 Манипуляторы и ввод/вывод в массив

Поскольку потоки для ввода/вывода в массив те же самые, что и другие потоки, то созданные вами манипуляторы могут использоваться также для ввода/вывода в массивы. Например, в прошлой главе был создан манипулятор для вывода setup(), который включал левое выравнивание и устанав­ливал ширину поля, равную 10, а в качестве символа заполнения определял знак $. Этот манипулятор может без изменений использоваться при выводе в массив, как показано ниже:

#include <strstrea.h>

#include <iostream.h>

#include <iomanip.h>

ostream& setup(ostream &stream)

{

stream.setf(ios::left);

stream << setw(10) << setfill('$');

return stream;

}

int main()

{

char str[80];

ostrstream outs(str, sizeof(str));

outs << setup << 99 << ends;

cout << str << endl;

return 0;

}