Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Программирование » Язык программирования C++. Пятое издание - Стенли Липпман

Язык программирования C++. Пятое издание - Стенли Липпман

Читать онлайн Язык программирования C++. Пятое издание - Стенли Липпман

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 121 122 123 124 125 126 127 128 129 ... 297
Перейти на страницу:

9.5.5. Числовые преобразования

Строки зачастую содержат символы, которые представляют числа. Например, числовое значение 15 можно представить как строку с двумя символами, '1' и '5'. На самом деле символьное представление числа отличается от его числового значения. Числовое значение 15, хранимое в 16-разрядной переменной типа short, будет иметь двоичное значение 0000000000001111, а символьная строка "15", представленная как два символа из набора Latin-1, будет иметь двоичное значение 0011000100110101. Первый байт представляет символ '1', восьмеричное значение которого составит 061, а второй байт, представляющий символ '5', в наборе Latin-1 имеет восьмеричное значение 065.

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

Таблица 9.16. Преобразования между строками и числами

to_string(val) Перегруженные версии функции возвращают строковое представление значения val. Аргумент val может иметь любой арифметический тип (см. раздел 2.1.1). Есть версии функции to_string() для любого типа с плавающей точкой и целочисленного типа, включая тип int и большие типы. Малые целочисленные типы преобразуются, как обычно (см. раздел 4.11.1) stoi(s, p, b) stol(s, p, b) stoul(s, p, b) stoll(s, p, b) stoull(s, p, b) Возвращают числовое содержимое исходной подстроки s как тип int, long, unsigned long, long long или unsigned long long соответственно. Аргумент b задает используемое для преобразования основание числа; по умолчанию принято значение 10. Аргумент p — указатель на тип size_t, означающий индекс первого нечислового символа в строке s; по умолчанию p имеет значение 0. В этом случае функция не хранит индекс stof(s, p) stod(s, p) stold(s, p) Возвращают числовое содержимое исходной подстроки s как тип float, double или long double соответственно. Аргумент p имеет то же назначение, что и у целочисленных преобразований

int i = 42;

string s = to_string(i); // преобразует переменную i типа int в ее

                         // символьное представление

double d = stod(s);      // преобразует строку s в значение типа double

Здесь для преобразования числа 42 в его строковое представление используется вызов функции to_string(), а затем вызов функции stod() преобразует эту строку в значение с плавающей точкой.

Первый преобразуемый в числовое значение символ строки должен быть цифрой:

string s2 = "pi = 3.14";

// d = 3.14 преобразуется первая подстрока в строке s, начинающаяся

// с цифры; d = 3.14

d = stod(s2.substr(s2.find_first_of("+-.0123456789")));

Для получения позиции первого символа строки s, который мог быть частью числа, в этом вызове функции stod() используется функция find_first_of() (см. раздел 9.5.3). Функции stod() передается подстрока строки s, начиная с этой позиции. Функция stod() читает переданную строку до тех пор, пока не встретится символ, который не может быть частью числа. Затем найденное символьное представление числа преобразуется в соответствующее значение типа double.

Первый преобразуемый символ строки должен быть знаком + или - либо цифрой. Строка может начаться с части 0x или 0X, означающей шестнадцатеричный формат. У функций преобразования чисел с плавающей точкой строка может также начинаться с десятичной точки (.) и содержать символ е или E, означающий экспоненциальную часть. У функций преобразования в целочисленный тип, в зависимости от основания, строка может содержать алфавитные символы, соответствующие цифрам после цифры 9.

Если строка не может быть преобразована в число, эти функции передают исключение invalid_argument (см. раздел 5.6). Если преобразование создает значение, которое не может быть представлено заданным типом, они передают исключение out_of_range.

Упражнения раздела 9.5.5

Упражнение 9.50. Напишите программу обработки вектора vector<string>, элементы которого представляют целочисленные значения. Вычислите сумму всех элементов вектора. Измените программу так, чтобы она суммировала строки, которые представляют значения с плавающей точкой.

Упражнение 9.51. Напишите класс, у которого есть три беззнаковых члена, представляющих год, месяц и день. Напишите конструктор, получающий строку, представляющую дату. Конструктор должен понимать множество форматов даты, такие как January 1,1900, 1/1/1900, Jan 1,1900 и т.д.

9.6. Адаптеры контейнеров

Кроме последовательных контейнеров, библиотека предоставляет три адаптера последовательного контейнера: stack (стек), queue (очередь) и priority_queue (приоритетная очередь). Адаптер (adaptor[4]) — это фундаментальная концепция библиотеки. Существуют адаптеры контейнера, итератора и функции. По существу, адаптер — это механизм, заставляющий нечто одно действовать как нечто другое. Адаптер контейнера получает контейнер существующего типа и заставляет его действовать как другой. Например, адаптер stack получает любой из последовательных контейнеров (array и forward_list) и заставляет его работать подобно стеку. Функции и типы данных, общие для всех адаптеров контейнеров, перечислены в табл. 9.17.

Таблица 9.17. Функции и типы, общие для всех адаптеров

size_type Тип данных, достаточно большой, чтобы содержать размер самого большого объекта этого типа value_type Тип элемента container_type Тип контейнера, на базе которого реализован адаптер A a; Создает новый пустой адаптер по имени a A a(c); Создает новый адаптер по имени а, содержащий копию контейнера с операторы сравнения Каждый адаптер поддерживает все операторы сравнения: ==, !=, <, <=, > и >=. Эти операторы возвращают результат сравнения внутренних контейнеров a.empty() Возвращает значение true, если адаптер а пуст, и значение false в противном случае a.size() Возвращает количество элементов в адаптере a swap(a, b) a.swap(b) Меняет содержимое контейнеров а и b; у них должен быть одинаковый тип, включая тип контейнера, на основании которого они реализованы Определение адаптера

Каждый адаптер определяет два конструктора: стандартный конструктор, создающий пустой объект, и конструктор, получающий контейнер и инициализирующий адаптер, копируя полученный контейнер. Предположим, например, что deq — это двухсторонняя очередь deque<int>. Ее можно использовать для инициализации нового стека следующим образом:

stack<int> stk(deq); // копирует элементы из deq в stk

По умолчанию оба адаптера, stack и queue, реализованы на основании контейнера deque, а адаптер priority_queue реализован на базе контейнера vector. Заданный по умолчанию тип контейнера можно переопределить, указав последовательный контейнер как второй аргумент при создании адаптера:

// пустой стек, реализованный поверх вектора

stack<string, vector<string>> str_stk;

// str_stk2 реализован поверх вектора и первоначально содержит копию

svec stack<string, vector<string>> str_stk2(svec);

Существуют некоторые ограничения на применение контейнеров с определенными адаптерами. Всем адаптерам нужна возможность добавлять и удалять элементы. В результате они не могут быть основаны на массиве. Точно так же нельзя использовать контейнер forward_list, поскольку все адаптеры требуют функций добавления, удаления и обращения к последнему элементу контейнера. Стек требует только функций push_back(), pop_back() и back(), поэтому для стека можно использовать контейнер любого из остальных типов. Адаптеру queue требуются функции back(), push_back(), front() и push_front(), поэтому он может быть создан на основании контейнеров list и deque, но не vector. Адаптеру priority_queue в дополнение к функциям front(), push_back() и pop_back() требуется произвольный доступ к элементам; он может быть основан на контейнерах vector и deque, но не list.

1 ... 121 122 123 124 125 126 127 128 129 ... 297
Перейти на страницу:
На этой странице вы можете бесплатно скачать Язык программирования C++. Пятое издание - Стенли Липпман торрент бесплатно.
Комментарии