atol () v / s. strtol()
в чем разница между atol() & strtol()?
согласно их man-страницам, они, похоже, имеют тот же эффект, что и соответствующие аргументы:
long atol(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
в обобщенном случае, когда я не хочу использовать base аргумент (у меня просто десятичные числа), какую функцию я должен использовать?
7 ответов:
strtolпредоставляет вам большую гибкость, так как он может фактически сказать вам, была ли вся строка преобразована в целое число или нет.atol, когда не удается преобразовать строку в число (например, вatol("help")), возвращает 0, которое неотличимо отatol("0"):int main() { int res_help = atol("help"); int res_zero = atol("0"); printf("Got from help: %d, from zero: %d\n", res_help, res_zero); return 0; }выходы:
Got from help: 0, from zero: 0
strtolуточню, используя его
atolфункциональность является подмножествомstrtolфункциональность, за исключением того, чтоatolобеспечивает вас без годных к употреблению возможностей обработки ошибок. Самая заметная проблема сato...функции заключается в том, что они приводят к неопределенному поведению в случае переполнения. Примечание: это не просто отсутствие информативной обратной связи в случае ошибки, это неопределенное поведение, т. е. обычно неисправимый сбой.это означает, что
atolфункция (как и все другиеato..функции) в значительной степени бесполезны для любых серьезных практических целей. Это была ошибка дизайна, и ее место находится на свалке истории C. Вы должны использовать функции изstrto...группа для выполнения преобразований. Они были введены, среди прочего, для исправления проблем, присущих функциямato...группы.
По словам
atoiman page, он был осужденstrtol.IMPLEMENTATION NOTES The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() and should not be used in new code.
в новом коде я бы всегда использовал
strtol. Он имеет обработку ошибок иendptrаргумент позволяет увидеть, какая часть строки была использована.в стандарте C99 говорится о
ato*функции:за исключением поведения при ошибке, они эквивалентны
atoi: (int)strtol(nptr,(char **)NULL, 10)atol: strtol(nptr,(char **)NULL, 10)atoll: strtoll(nptr, (char **)NULL, 10)
atol(str)эквивалентноstrtol(str, (char **)NULL, 10);используйте strtol, если вы хотите, чтобы указатель конца (чтобы проверить, есть ли больше символов для чтения или если на самом деле вы читали вообще) или база, отличная от 10. В противном случае, АТОЛ в порядке.
если память не изменяет,
strtol()имеет дополнительное преимущество для установки (необязательно)endptrчтобы указать на первый символ, который не удалось преобразовать. ЕслиNULL, оно игнорируется. Таким образом, если вы обрабатываете строку, содержащую смешанные числа и символы, вы можете продолжить.например,
char buf[] = "213982 and the rest"; char *theRest; long int num = strtol(buf, &theRest, 10); printf("%ld\n", num); /* 213982 */ printf("%s\n", theRest); /* " and the rest" */
man страница strtol дает следующее:
ERRORS EINVAL (not in C99) The given base contains an unsupported value. ERANGE The resulting value was out of range. The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).следующий код проверяет наличие ошибок диапазона. (Модифицированный код Эли немного)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int main() { errno = 0; char* end = 0; long res = strtol("83459299999999999K997", &end, 10); if(errno != 0) { printf("Conversion error, %s\n", strerror(errno)); } else if (*end) { printf("Converted partially: %i, non-convertible part: %s\n", res, end); } else { printf("Converted successfully: %i\n", res); } return 0; }
Comments