ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 12) онлайн

Память как поток

Область памяти можно считать потоком и записывать в нее данные точно так же, как в файл. Это требуется, когда нужно выводить данные в определенном фор- мате (например, оставлять только два знака после запятой) и одновременно ис- пользовать функцию текстового вывода, которая в качестве аргумента требует строку. Так обычно делают, вызывая функции вывода, при разработке приложе- ний в GUI-средах, например в Windows, поскольку там этим функциям нужно передавать именно строку в качестве аргумента. Программисты на C, вероятно, сразу вспомнят, как они использовали sprintf() для этих целей.

Семейство потоковых классов поддерживает такое форматирование данных в памяти. Для вывода в память существует специальный класс ostrstream, порож- денный классом ostream. Для ввода из памяти служит класс istrstream, порожден- ный, соответственно, классом istream. Для объектов, которым требуется осуще- ствлять одновременно ввод и вывод, создан класс strstream — наследник iostream.

Скорее всего, вы захотите использовать ostrstream. Наш следующий пример показывает, как это реально применить на практике. Начните с создания буфера данных в памяти. Затем сваяйте объект ostrstream, используя этот буфер (его ад- рес и размер) в качестве аргументов конструктора потока. Теперь можно выво- дить форматированный текст в буфер, как если бы он был потоковым объектом.

Листинг 12.20. Программа OSTRSTR

// ostrstr.cpp

// Запись форматированных данных в память

#include <strstream>

#include <iostream>

#include <iomanip>        // для функции setiosflags()

using namespace std;

const int SIZE = 80;      // размер буфера

 

int main()

{

  char ch = 'x';          // тестовые данные

  int j = 77;

  double d = 67890.12345;

  char str1[] = "Kafka";

  char str2[] = "Freud";

 

  char membuff[SIZE];             // буфер в памяти

  ostrstream omem(membuff, SIZE); // создать потоковый объект

Листинг 12.20 (продолжение)

  omem << "ch=" << ch << endl      // вставить форматированные данные

      << "j=" << j << endl         // в объект

      << setiosflags(ios::fixed)    // формат с десятичной запятой (фиксированной)

      << setprecision(2)              // оставлять два знака после запятой                                 

      << "d=" << d << endl

      << "str1=" << str1 << endl

      << "str2=" << str2 << endl

      << ends;         // закончить буфер символом '\0'

  cout << membuff;     // вывод содержимого буфера

  return 0;

}

 

После запуска программы membuff заполнится форматированным текстом:

ch-x\nj=77\nd=67890.12\nstr1=Kafka\nstr2=Freud\n\0

Можно форматировать данные с плавающей запятой привычными способа- ми. Здесь же мы используем формат с фиксированной запятой (не экспоненци- альный), указав на это с помощью ios::fixed, при этом оставляем два знака после запятой. Манипулятор ends вставляет в конец строки служебный символ '\0' для создания признака EOF. Вывод на экран содержимого буфера с использованием обычного cout дает такой результат:

ch=x j =77

d=67890.12 str1=Kafka str2=Freud

 

Здесь выводится содержимое буфера просто для демонстрации того, что кое- что из написанного в нашей программе работает. Вообще же, конечно, такие ме- тоды используются для более сложных операций с данными.

 

43