Я действительно смущен. Я должен упустить что-то довольно простое, но ничего, что я читаю о strtol (), не имеет смысла. Может ли кто-нибудь изложить это для меня по-настоящему простым способом, а также привести пример того, как я мог бы заставить что-то вроде следующего работать?
string input = getUserInput;
int numberinput = strtol(input,?,?);
Первый аргумент — это строка. Он должен быть передан как строка C, так что если у вас есть std::string
использование .c_str()
первый.
Второй аргумент является необязательным и определяет char *
хранить указатель на символ после конца числа. Это полезно при преобразовании строки, содержащей несколько целых чисел, но если вам это не нужно, просто установите для этого аргумента значение NULL.
Третий аргумент — основа (основание) для преобразования. strtol
может сделать что-нибудь от двоичного (база 2) до базы 36. Если вы хотите strtol
чтобы автоматически выбрать базу на основе префикса, введите 0.
Итак, простейшее использование будет
long l = strtol(input.c_str(), NULL, 0);
Если вы знаете, что получаете десятичные числа:
long l = strtol(input.c_str(), NULL, 10);
strtol
возвращает 0, если в начале строки нет конвертируемых символов. Если вы хотите проверить, если strtol
успешно, используйте средний аргумент:
const char *s = input.c_str();
char *t;
long l = strtol(s, &t, 10);
if(s == t) {
/* strtol failed */
}
Если вы используете C ++ 11, используйте stol
вместо:
long l = stol(input);
Кроме того, вы можете просто использовать stringstream
Преимущество заключается в том, что вы можете легко читать многие элементы, как cin
:
stringstream ss(input);
long l;
ss >> l;
Предположим, вам дали строку char const * str
, Теперь преобразуйте это так:
#include <cstdlib>
#include <cerrno>
char * e;
errno = 0;
long n = std::strtol(str, &e, 0);
Последний аргумент 0
определяет базу номеров, которую вы хотите применить; 0
означает «автоопределение». Другие разумные ценности 8
, 10
или же 16
,
Далее нужно осмотреть указатель конца e
, Это указывает на символ после потребленного ввода. Таким образом, если весь ввод был использован, он указывает на нулевой терминатор.
if (*e != '\0') { /* error, die */ }
Также возможно учесть частичное потребление, используя e
, но это тот тип вещей, который вы поймете, когда вам это действительно понадобится.
Наконец, вы должны проверить на наличие ошибок, которые по сути могут быть только ошибками переполнения, если входные данные не вписываются в тип назначения:
if (errno != 0) { /* error, die */ }
В C ++ может быть предпочтительнее использовать std::stol
хотя в этом случае вы не можете выбрать номер базы:
#include <string>
try { long n = std::stol(str); }
catch (std::invalid_argument const & e) { /* error */ }
catch (std::out_of_range const & e) { /* error */ }
Цитата из C ++ ссылка:
long int strtol ( const char * str, char ** endptr, int base );
Преобразовать строку в длинное целое
Анализирует строку C str, интерпретируя ее содержимое как целое число указанной базы, которое возвращается как длинное значение типа int. Если endptr не является нулевым указателем, функция также устанавливает значение endptr, указывающее на первый символ после числа.
Так что попробуйте что-то вроде
long l = strtol(pointerToStartOfString, NULL, 0)
Я всегда использую просто strol(str,0,0)
— возвращает длинное значение. 0 для radix (последний параметр) означает автоматическое определение его по входной строке, поэтому оба 0x10
как гекс и 10
в качестве десятичной можно использовать во входной строке.