if (hexStr.length( ) > 2) {

  if (hexStr[0] == '0' && hexStr[1] == 'x') {

   return strtol(hexStr.c_str(), &offset, 0);

  }

 }

 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 показывает как он используется.

Пример 3.2. Использование lexical_cast

#include

#include

#include

using namespace std;

int main() {

 string str1 = "750" ;

 string str2 = "2.71";

 string str3 = "0x7FFF";

 try {

  cout << boost::lexical_cast(str1) << endl;

  cout << boost::lexical_cast(str2) << endl;

  cout << boost::lexical_cast(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, которая объявлена в . Эквивалентами функций strtod и strtoul являются wcstod и wcstoul. Каждая из этих функций точно такая же, за исключением того, что те параметры, которые в функциях для узких символов имеют тип char*, в функциях для широких символов имеют тип wchar_t*.

Смотри также

Рецепт 3.2.

<p>3.2. Преобразование чисел в строки</p>Проблема

Имеются числовые типы (int, float), и вам требуется поместить их содержимое в string, возможно, предварительно отформатировав.

Решение
Перейти на страницу:

Похожие книги