Чтение онлайн

ЖАНРЫ

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

В моей корзине 9 яблок.

ss = 0x10

ss = 3.14

Обсуждение

stringstream
— это удобный способ поместить данные в
string
, поскольку он позволяет использовать все возможности форматирования, предоставляемые классами стандартного ввода и вывода. В простейшем случае в примере 3.3 я для записи комбинации текста и числовых данных в строковый поток просто использую оператор сдвига влево (
<<
).

ss << "В моей корзине " << 9 << " яблок.";

Оператор

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

cout << ss.str << endl;

В

<iomanip>
имеется большое количество манипуляторов потоками, и их использование при выводе числовых данных в строку позволяет выполнить все виды форматирования. В примере 3.3 для форматирования числа как шестнадцатеричного я использовал
showbase
и
hex
, но есть еще и другие возможности форматирования. Например, можно установить точность отображения, отличную от числа десятичных знаков по умолчанию.

ss << setprecision(6) << 3.14285;

Однако использование манипуляторов является не самой интуитивно понятной вещью, и именно поэтому создан рецепт, посвященный им. За дополнительной информацией о форматировании числовых данных с помощью манипуляторов потоками обратитесь к рецепту 10.2.

Конечно, как часто бывает в С++, имеется и другой способ. Библиотека Boost Format (написанная Сэмюэлем Кремппом (Samuel Krempp) содержит класс

format
, который делает форматирование и преобразование очень простыми. Пример 3.4 показывает, как выполнить подобное преобразование.

Пример 3.4. Форматирование целых в шестнадцатеричное представление

#include <iostream>

#include <boost/format.hpp>

using namespace std;

using boost::format;

using boost.:io::str;

using boost::io::format_error;

int main {

 try {

format f("Имеется %1% способа. %2% %3% %4%");

f % 3;

f % "чтобы" % "это" % "сделать.";

cout << f << endl;

f.clear; // Счистка буферов для форматирования чего-либо еще

f.parse("Это стоит $%d.");

f % 50;

cout << f << endl;

int x = 11256099;

string strx = str(format("%x") % x);

cout << strx << endl;

 } catch (format_error &e) {

cout << e.what << endl;

 }

}

Вот что вы увидите при запуске этой программы.

Имеется 3 способа, чтобы это сделать.

Это стоит $50.

abc123

Использование класса

format
требует двух шагов, включая создание объекта
format
и передачу ему содержимого. Для простейшего случая в примере 3.4 я создал объект format с помощью
простейшей версии его синтаксиса.

format f(" Имеется %1% способа, %2% %3% %4%");

В строке формата заполнители — это числа, обрамленные с обеих сторон символами %. Затем я начинаю передавать в объект содержимое указанного формата.

f % 3;

f % "чтобы" % "это" % "сделать;

Оператор

%
в библиотеке форматирования был переопределен так, чтобы добавлять указанные в нем переменные в левую часть объекта
format
. Его можно использовать как один раз на строку, так и несколько раз в одной строке. Он аналогичен оператору
<<
для строк. Что же касается оператора
<<
, он также был переопределен так, что объекты
format
можно непосредственно записать в выходной поток. Кроме того, если требуется поместить результаты в строку, используйте функцию-член
str
.

string s = f.str;

Если же вам нравится

printf
, то можно использовать форматную строку
printf
.

f.parse("Это стоит $%d.*");

f % 50;

Если будет записано слишком много или слишком мало переменных для указанного формата, то при попытке записать строку в поток или извлечь отформатированную строку будет выброшено исключение

format_error
(или подкласс
thereof
).

Класс

format
достаточно мощен и содержит слишком много возможностей форматирования, чтобы их можно было описать здесь, и его стоит изучить. Чтобы скачать Boost или почитать документацию, посетите web-сайт Boost по адресу www.boost.org.

Также для преобразования чисел из числовых типов в строки можно использовать

sprintf
или аналогичные ей функции. Обычно этого следует избегать, так как это небезопасно и для этого имеются лучшие альтернативы.

Смотри также

Глава 10.

3.3. Проверка, содержит ли строка допустимое число

Проблема

Имеется строка

string
и требуется определить, содержит ли она допустимое число.

Решение

Для проверки допустимости числа можно использовать шаблон функции

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

Пример 3.5. Проверка числовой строки

#include <iostream>

#include <boost/lexical_cast.hpp>

using namespace std;

using boost::lexical_cast;

using boost::bad_lexical_cast;

template<typename T>

bool isValid(const string& num) {

 bool res = true;

 try {

T tmp = lexical_cast<T>(num);

 } catch (bad_lexical_cast &e) {

res = false;

 }

Поделиться с друзьями: