|
Программирование >> Операторы преобразования типа
и ios::ate символы, записанные в строковый поток данных, присоединяются к существующей строке: std::string s; std::ostr1ngstream os (s. ios::outiosapp): OS 77 std::hex 77: Однако строка, возвращаемая функцией str(), представляет собой копию строки s с присоединенными значениями 77 в десятичном и шестнадцатеричном виде. Сама строка s остается неизменной. Потоковые классы char ! Потоковые классы char* поддерживаются только в целях обратной совместимости. Их интерфейс иногда порождает ошибки, с зтими классами часто работают неправильно. Тем не менее они продолжают широко использоваться, поэтому далее приводятся их краткие описания. Учтите, что в описываемой здесь стандартной версии прежний интерфейс был слегка изменен. Далее вместо термина строка будет использоваться термин последовательность символов. Дело в том, что последовательность символов, поддерживаемая потоковыми классами char*, не всегда заканчивается символом завершения строки (а следовательно, не является строкой в обычном понимании). Потоковые классы char* определены только для символьного типа char. К этой категории относятся следующие классы: О istrstream для чтения из последовательностей символов; О ostrstream для записи в последовательности символов; О strstream для чтения из последовательностей символов и записи в последовательности символов; О strstreambuf используется как потоковый буфер для потоков char*. Потоковые классы char* определяются в заголовочном файле <strstream>. Поток данных istrstream может инициализироваться последовательностью символов (типа char*), либо завершенной символом \0, либо имеющей длину, переданную в аргументе. Типичный пример чтения и обработки строк: char buffer[1000]: Буфер, в котором могут храниться до 999 символов Чтение строки std::Cln.get(buffer.s1zeof(buffer)): Чтение/обработка строки как потока std::Istrstream 1nput(buffer): input x: Поток данных char*, предназначенной для записи, поддерживает последовательность символов, растущую по мере необходимости, или инициализируется буфером фиксированного размера. При помощи флагов ios::app и io5::ate можно дописывать выводимые символы к последовательности, уже хранящейся в буфере. При строковой интерпретации потока данных char* необходима осторожность. В отличие от строковых потоков данных потоки типа char* не всегда следят за использованием памяти, в которой хранится последовательность символов. Функция str() предоставляет вызывающей стороне доступ к последовательности символов вместе с ответственностью за управление соответствующей памятью. Если поток данных не был инициализирован буфером фиксированного размера (за который поток никогда не отвечает), должны соблюдаться следующие трн правила. О Поскольку права владения памятью передаются вызывающей стороне (если поток данных не был инициализирован буфером фиксированного размера), символьная последовательность должна освобождаться. Но так как не гарантируется, что память выделялась вызов delete[] не всегда безопасен. Лучше всего вернуть память в поток данных вызовом функции freeze с аргументом false (пример приводится далее). О Вызов str() запрещает потоку данных дальнейшее изменение последовательности символов. Функция неявно вызывает функцию freeze(), которая фиксирует ( замораживает*) последовательность символов. Это делается для того, чтобы избежать трудностей при недостаточном размере буфера и необходимости выделять новую память. О Функция str() не присоединяет символ завершения строки (\0). Это символ приходится отдельно присоединять к потоку данных для завершения последовательности символов. Задача решается при помощи манипулятора ends. Некоторые реализации присоединяют символ завершения строки автоматически, но это поведение нарушает переносимость программы. Пример использования потока char*: float X; /* Создание и заполнение потока char* * - не забывайте о ends или \0!!1 */ std:;ostrstream buffer; Динамический потоковый буфер buffer float х: х std;:ends: Передача полученной С-строки функции foo() и возвращение памяти в буфер char* S - buffer.strO; foo(s): buffer.freeze(fa1se): Зафиксированный поток char* можно привести в обычное состояние для дополнительной обработки. Для этого следует вызвать функцию freeze() с аргу- Имеется конструктор, в аргументах которого передаются два указателя на функции: для выделения и освобождения памяти. ментом false. При выполнении этой операции право владения последовательностью символов снова возвращается объекту потока данных. Это единственный безопасный способ освобождения памяти для последовательности символов. В следующем примере показано, как это делается: float X: std:;ostrstream buffer: Динамический поток char* Заполнение потока char* buffer float x: x std::ends; /* Передача итоговой С-строки функции fooO * - фиксация потока char* */ fooCbuffer.strO); Снятие фиксации с потока char* buffer.freeze(false): Установка позиции записи в начало buffer.seekp (О, ios::beg); Повторное заполнение потока char* buffer once more float x: x std::ends: /* Повторная передача полученной С-строки функции foo() * - фиксация потока char*; */ fooCbuffer.strO); Возвращение памяти в буфер buffer.freeze(false); Проблем, возникающих из-за фиксации потока данных, нет в классах строковых потоков данных. В основном это объясняется тем, что использование памяти при копировании находится под контролем строкового класса. Операторы ввода-вывода для пользовательских типов Как упоминалось ранее, главным преимуществом потокового ввода-вывода перед средствами ввода-вывода языка С является возможность расширения потокового механизма для пользовательских типов. Расширение основано на перегрузке операторов << и >>. Далее рассматривается пример использования потоков данных для вывода правильных дробей.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |