В начале этой главы при связывании потока с массивом для вывода данных этот массив и его размер передавались конструктору класса ostrstream. Такой подход работает до тех пор, пока известно максимальное количество символов, которое потребуется вывести в массив. Что же делать, когда заранее неизвестно, насколько большой массив понадобится в дальнейшем? Решением этой проблемы служит вторая форма конструктора ostrtream, показанная ниже:
ostrtream();
При использовании этого конструктора ostrstream создает и поддерживает динамически выделяемый массив. Этот массив может расти по величине в соответствии с объемом данных, которые необходимо в нем хранить.
Для доступа к динамически выделяемому массиву следует использовать функцию str(). Она имеет следующий прототип:
char* str();
Эта функция «замораживает» массив и возвращает указатель на него. Как только массив заморожен, он не может снова использоваться для вывода данных. Поэтому не следует замораживать массив, пока продолжается запись в него символов.
Следующая программа использует динамический массив:
Как показывает эта программа, если заморозить массив, то придется самостоятельно освободить память при выходе из функции или программы. Однако если массив не заморожен, память будет освобождена автоматически при уничтожении потока ввода/вывода.
Можно также использовать динамические массивы с классом strstream, позволяющим как вводить, так и выводить данные в массив.
8.8 Манипуляторы и ввод/вывод в массив
Поскольку потоки для ввода/вывода в массив те же самые, что и другие потоки, то созданные вами манипуляторы могут использоваться также для ввода/вывода в массивы. Например, в прошлой главе был создан манипулятор для вывода setup(), который включал левое выравнивание и устанавливал ширину поля, равную 10, а в качестве символа заполнения определял знак $. Этот манипулятор может без изменений использоваться при выводе в массив, как показано ниже: