return strtol(hexStr.c_str( ), &offset, 16);
}
int main() {
string str1 = '0x12AB';
cout << hex2int(str1) << endl;
string str2 = '12AB';
cout << hex2int(str2) << endl;
string str3 = '0AFG';
cout << hex2int(str3) << endl;
}
Вот вывод этой программы.
4779
4779
0
Первые две строки содержат шестнадцатеричное число 12AB. Первая из них содержит префикс 0x
, а вторая — нет. Третья строка не содержит правильного шестнадцатеричного числа. В этом случае функция просто возвращает 0.
Некоторые люди склонны писать свои собственные функции для преобразования шестнадцатеричных чисел в целочисленные форматы. Но зачем изобретать колесо? Стандартная библиотека уже предоставляет эту функциональность. Пример 3.1 представляет собой функцию-оболочку, упрощающую вызов strtol
. Функция strtol
— это старая функция библиотеки С, и она требует от вас передачи указателя на завершающуюся нулем строку, а так же адрес еще одного указателя на строку. Этот второй указатель получает адрес, на котором обработка строки завершилась. Однако в C++ большинство людей предпочитает работать с более мощным классом string
, а не со старыми указателями на символьные строки. Поэтому функция hex2int
принимает параметр типа string
.
Функция strtol
несколько странна в том, что она позволяет использовать два разных метода указания основания 16: 16 можно передать как третий параметр функции, а можно в качестве основания передать 0, но предварить строку символами 0x
(точно также, как это делается для обозначения шестнадцатеричных чисел в коде, но только помните, что в случае с strtol
передается строка).
Пример 3.1 позволяет использовать оба метода. При передаче строки вида 0x12AB
функция обнаружит 0x
и передаст ее непосредственно в strtol
, в качестве третьего параметра передав 0. В противном случае функция передаст строку, в качестве третьего параметра передав 16.
strtol
и strtoul
работают одинаково, за исключением типа возвращаемого значения. strtod
аналогична им, но не позволяет указывать основание.
Эти старые функции С не являются единственным способом преобразования строк в числа. Проект Boost предоставляет класс преобразования lexical_cast
, который выполняет то же самое для числовых строк, записанных с основанием 10. Пример 3.2 показывает как он используется.
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
using namespace std;
int main() {
string str1 = '750' ;
string str2 = '2.71';
string str3 = '0x7FFF';
try {
cout << boost::lexical_cast<int>(str1) << endl;
cout << boost::lexical_cast<double>(str2) << endl;
cout << boost::lexical_cast<int>(str3) << endl;
} catch (boost::bad_lexical_cast& e) {
cerr << 'Bad cast: ' << e.what() << endl;
}
}
Вывод примера 3.2 таков.
750
2.71
Bad cast: bad lexical cast: source type value could not be
interpreted as target
(Неверное преобразование: неверное лексическое преобразование: значение исходного типа не может быть преобразовано в целевой.)
Вы ведите, что для последнего значения, представляющего собой шестнадцатеричное число, он выбрасывает исключение. При преобразовании чисел с основанием, отличным от 10, требуется использовать функции strtol
.
Также имеются версии функций strtol
для работы с «широкими» символами. Эквивалент strtol
для работы с широкими символами — это wcstol
, которая объявлена в <cwchar>
. Эквивалентами функций strtod
и strtoul
являются wcstod
и wcstoul
. Каждая из этих функций точно такая же, за исключением того, что те параметры, которые в функциях для узких символов имеют тип char*
, в функциях для широких символов имеют тип wchar_t*
.
Рецепт 3.2.
3.2. Преобразование чисел в строки
Имеются числовые типы (int
, float
), и вам требуется поместить их содержимое в string
, возможно, предварительно отформатировав.
Для выполнения этого имеется множество способов, каждый из которых имеет свои достоинства и недостатки. Первая представляемая мной методика использует для хранения строковых данных класс stringstream
, который является частью стандартной библиотеки и прост в использовании. Этот подход показан в примере 3.3. Смотри обсуждение альтернативных методик.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;