Функция 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.
3.2. Преобразование чисел в строки
Проблема
Имеются числовые типы ( int, float), и вам требуется поместить их содержимое в string, возможно, предварительно отформатировав.
Решение
Для выполнения этого имеется множество способов, каждый из которых имеет свои достоинства и недостатки. Первая представляемая мной методика использует для хранения строковых данных класс stringstream, который является частью стандартной библиотеки и прост в использовании. Этот подход показан в примере 3.3. Смотри обсуждение альтернативных методик.
Пример 3.3. Форматирование числа как строки
#include
#include
#include
#include
using namespace std;
int main() {
stringstream ss;
ss << "В моей корзине " << 9 << " яблок.";
cout<<
// с содержимым
ss.str(""); // Очистка строки
ss << showbase << hex << 16; // Показать основание в шестнадцатеричном формате
cout << "ss = " << ss.str() << endl;
ss.str("");
ss << 3.14;
cout << "ss = " << ss.str() << endl;
}
Вывод примера 3.3 выглядит так.
В моей корзине 9 яблок.
ss = 0x10
ss = 3.14
Обсуждение
stringstream— это удобный способ поместить данные в string, поскольку он позволяет использовать все возможности форматирования, предоставляемые классами стандартного ввода и вывода. В простейшем случае в примере 3.3 я для записи комбинации текста и числовых данных в строковый поток просто использую оператор сдвига влево ( <<).
ss << "В моей корзине " << 9 << " яблок.";
Оператор <<перегружен для встроенных типов и соответственно форматирует вывод. Когда требуется получить данные, хранящиеся в string, используйте функцию-член str.
cout << ss.str() << endl;
В имеется большое количество манипуляторов потоками, и их использование при выводе числовых данных в строку позволяет выполнить все виды форматирования. В примере 3.3 для форматирования числа как шестнадцатеричного я использовал showbaseи hex, но есть еще и другие возможности форматирования. Например, можно установить точность отображения, отличную от числа десятичных знаков по умолчанию.
Читать дальше