Выбрать главу

#include sstream

Например, следующая функция читает весь файл alice_emma в объект buf класса ostringstream. Размер buf увеличивается по мере необходимости, чтобы вместить все символы: #include string #include fstream #include sstream string read_file_into_string() { ifstream ifile( "alice_emma" ); ostringstream buf; char ch; while ( buf && ifile.get( ch )) buf.put( ch ); return buf.str(); }

Функция-член str() возвращает строку – объект класса string, ассоциированный со строковым потоком ostringstream. Этой строкой можно манипулировать так же, как и “обычным” объектом класса string. Например, в следующей программе text почленно инициализируется строкой, ассоциированной с buf:

int main()

{

string text = read_file_into_string();

// запомнить позиции каждого символа новой строки

vector string::size_type lines_of_text;

string::size_type pos = 0;

while ( pos != string::npos )

{

pos = text.find( '\n' pos );

lines_of_text.push_back( pos );

}

// ...

}

Объект класса ostringstream можно использовать для автоматического форматирования составной строки, т.е. строки, составленной из данных разных типов. Так, следующий оператор вывода автоматически преобразует любой арифметический тип в соответствующее строковое представление, поэтому заботиться о выделении нужного количества памяти нет необходимости:

#include iostream

#include sstream

int main()

{

int ival = 1024; int *pival =

double dval = 3.14159; double *pdval =

ostringstream format_message;

// преобразование значений в строковое представление

format_message "ivaclass="underline" " ival

" адрес ivaclass="underline" " pival 'n'

"dvaclass="underline" " dval

" адрес dvaclass="underline" " pdval endl;

string msg = format_message.str();

cout " размер строки сообщения: " msg.size()

" сообщение:"msg endl;

}

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

string

format( string msg, int expected, int received )

{

ostringstream message;

message msg " ожидалось: " expected

" принято: " received "\n";

return message.str();

}

string format( string msg, vectorint *values );

// ... и так далее

Приложение может сохранить такие строки для последующего отображения и даже рассортировать их по серьезности. Обобщить эту идею помогают классы Notify (извещение), Log (протокол) и Error (ошибка).

Поток istringstream читает из объекта класса string, с помощью которого был сконструирован. В частности, он применяется для преобразования строкового представления числа в его арифметическое значение:

#include iostream

#include sstream

#include string

int main()

{

int ival = 1024; int *pival =

double dval = 3.14159; double *pdval =

// создает строку, в которой значения разделены пробелами

ostringstream format_string;

format_string ival " " pival " "

dval " " pdval endl;

// извлекает сохраненные значения в коде ASCII

// и помещает их в четыре разных объекта

istringstream input_istring( format_string.str() );

input_istring ival pival

dval pdval;

}

Упражнение 20.16

В языке Си форматирование выходного сообщения производится с помощью функций семейства printf(). Например, следующий фрагмент

int ival = 1024;

double dval = 3.14159;

char cval = 'a';

char *sval = "the end";

printf( "ivaclass="underline" %d\tdval% %g\tcvaclass="underline" %c\tsvaclass="underline" %s",

ival, dval, cval, sval );

печатает:

ivaclass="underline" 1024 dvaclass="underline" 3.14159 cvaclass="underline" a svaclass="underline" the end

Первым аргументом printf() является форматная строка. Каждый символ % показывает, что вместо него должно быть подставлено значение аргумента, а следующий за ним символ определяет тип этого аргумента. Вот некоторые из поддерживаемых типов (полное описание см. в [KERNIGHAN88]):

%dцелое число

%gчисло с плавающей точкой

%cchar

%sC-строка

Дополнительные аргументы printf() на позиционной основе сопоставляются со спецификаторами формата, начинающимися со знака %. Все остальные символы в форматной строке рассматриваются как литералы и выводятся буквально.

* Основные недостатки семейства функций printf() таковы: во-первых, форматная строка не обобщается на определенные пользователем типы, и, во-вторых, если типы или число аргументов не соответствуют форматной строке, компилятор не заметит ошибки, а вывод будет отформатирован неверно. Однако у функций printf() есть и достоинство – компактность записи. Получите так же отформатированный результат с помощью объекта класса ostringstream.