#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.