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

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

basic_string<Unicode> a_unicode_string;

Стандартный класс

string
, который мы используем, является просто классом
basic_string
, конкретизированным обычным типом
char
.

typedef basic_string<char> string; // строка — это basic_string<char>

Мы не будем описывать символы или строки кода Unicode, но при необходимости
вы можете работать с ними точно так же, как и с обычными символами и строками (к ним применяются точно такие же конструкции языка, класс
string
, потоки класса
iostream
и регулярные выражения). Если вам нужны символы кода Unicode, то лучше всего попросить совета у опытных пользователей; для того чтобы ваша программа стала полезной, вы должны не только выполнять правила языка, но и некоторые системные соглашения.

В контексте обработки текста важно помнить, что практически все можно представить в виде строки символов. Например, на этой странице число

12.333
представлено в виде строки, состоящей из шести символов и окруженной пробелами.

Если вы считываете это число, то должны сначала превратить эти символы в число с плавающей точкой и лишь потом применять к нему арифметические операции. Это приводит к необходимости конвертирования чисел в объекты класса
string
и объектов класса
string
в числа. В разделе 11.4 мы видели, как превратить целое число в объект класса
string
, используя класс ostringstream. Этот прием можно обобщить для любого типа, имеющего оператор
<<
.

template<class T> string to_string(const T& t)

{

ostringstream os;

os << t;

return os.str;

}

Рассмотрим пример.

string s1 = to_string(12.333);

string s2 = to_string(1+5*6–99/7);

Значение строки

s1
равно "
12.333
", а значение строки
s2
— "
17
". Фактически функцию
to_string
можно применять не только к числовым значениям, но и к любому классу
T
с оператором
<<
.

Обратное преобразование, из класса

string
в число, так же просто, как и полезно.

struct bad_from_string:std::bad_cast

// класс для сообщений об ошибках при преобразовании строк

{

const char* what const // override bad_cast’s what

{

return "bad cast from string";

}

};

template<class T> T from_string(const string& s)

{

istringstream is(s);

T t;

if (!(is >> t)) throw bad_from_string;

return t;

}

Рассмотрим пример.

double d = from_string<double>("12.333");

void do_something(const string& s)

try

{

int i = from_string<int>(s);

// ...

}

catch (bad_from_string e) {

error ("Неправильная
строка ввода",s);

}

Дополнительная сложность функции

from_string
по сравнению с функцией
to_string
объясняется тем, что класс
string
может представлять значения многих типов. Это значит, что каждый раз мы должны указывать, какой тип значений хотим извлечь из объекта класса
string
. Кроме того, это значит, что класс
string
, который мы изучаем, может не хранить значение типа, который мы ожидаем. Рассмотрим пример.

int d = from_string<int>("Mary had a little lamb"); // Ой!

Итак, возможна ошибка, которую мы представили в виде исключения типа

bad_from_string
. В разделе 23.9 мы покажем, что функция
from_string
(или эквивалентная) играет важную роль в серьезных текстовых приложениях, поскольку нам необходимо извлекать числовые значения из текстовых полей. В разделе 16.4.3 было показано, как эквивалентная функция
get_int
используется в графическом пользовательском интерфейсе.

Обратите внимание на то, что функции

to_string
и
from_string
очень похожи. Фактически они являются обратными друг другу; иначе говоря (игнорируя детали, связанные с пробелами, округлением и т.д.), для каждого “разумного типа
T
” имеем

s==to_string(from_string<T>(s)) // для всех s

и

t==from_string<T>(to_string(t)) // для всех t

Здесь слово “разумный” означает, что тип

T
должен иметь конструктор по умолчанию, оператор
>>
и соответствующий оператор
<<
.

Следует подчеркнуть, что реализации функций
to_string
и
from_string
используют класс
stringstream
для выполнения всей работы. Это наблюдение было использовано для определения универсальной операции конвертирования двух произвольных типов с согласованными операциями
<<
и
>>
.

struct bad_lexical_cast:std::bad_cast

{

const char* what const { return "bad cast"; }

};

template<typename Target,typename Source>

Target lexical_cast(Source arg)

{

std::stringstream interpreter;

Target result;

if (!(interpreter << arg) // записываем arg в поток

|| !(interpreter >> result) // считываем result из потока

|| !(interpreter >> std::ws).eof) // поток пуст?

Поделиться:
Популярные книги

Темный Лекарь 3

Токсик Саша
3. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 3

Лорд Системы 11

Токсик Саша
11. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 11

Мимик нового Мира 7

Северный Лис
6. Мимик!
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 7

Папина дочка

Рам Янка
4. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Папина дочка

Расческа для лысого

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
8.52
рейтинг книги
Расческа для лысого

Пограничная река. (Тетралогия)

Каменистый Артем
Пограничная река
Фантастика:
фэнтези
боевая фантастика
9.13
рейтинг книги
Пограничная река. (Тетралогия)

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

Уязвимость

Рам Янка
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Уязвимость

Ярость Богов

Михайлов Дем Алексеевич
3. Мир Вальдиры
Фантастика:
фэнтези
рпг
9.48
рейтинг книги
Ярость Богов

Лорд Системы 12

Токсик Саша
12. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 12

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Морозная гряда. Первый пояс

Игнатов Михаил Павлович
3. Путь
Фантастика:
фэнтези
7.91
рейтинг книги
Морозная гряда. Первый пояс

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...