Deklaracja strtol
w stdio.h
jest następujący:
long int strtol(const char *nptr, char **endptr, int base);
strtol
zapewnia niezawodne sprawdzanie błędów i walidacji systemu, który pozwala na określenie, czy wartość zwracana jest valid
lub invalid
. Zasadniczo masz do dyspozycji 3 podstawowe narzędzia. (1) wartość powrócił (2) wartość errno
jest ustawiony przez wywołanie i (3) adresy i zawartość nptr
i endptr
dostarczone i ustala, strtol
. (Aby uzyskać szczegółowe informacje, patrz: man 3 strtol
- przykład na stronie man
zapewnia także krótszy zestaw warunków do sprawdzenia, ale zostały one rozwinięte poniżej w celu wyjaśnienia).
W twoim przypadku pytasz o wartość zwracaną 0
i określasz, czy jest ona ważna. Jak widzisz, wartość 0
zwrócona przez strtol
wynosi , a nie oznacza, że odczytana liczba to 0
lub że 0
jest poprawna. Aby ustalić, czy kod 0
jest prawidłowy, należy również sprawdzić, czy podczas połączenia ustawiono wartość errno
(jeśli została ustawiona). W szczególności, jeśli errno != 0
i wartość zwrócona przez strtol
wynosi 0
, wówczas wartość zwrócona przez strtol
wynosi INVALID. (warunek ten będzie oznaczać invalid base
, lub overflow
z errno
równy albo EINVAL
lub ERANGE
).
Istnieje drugi warunek, który może spowodować, że strtol
zwróci INVALID0
. Przypadek, w którym nie podano cyfr w obrębie wejścia. Gdy to nastąpi, strtol
ustawia wartość endptr == nptr
. Dlatego należy również sprawdzić, czy wartości wskaźników są równe przed wprowadzeniem wartości 0
. (A WAŻNA0
mogą być wprowadzone z wielu 0's
w ciągu)
Poniżej przedstawiono krótki przykład zróżnicowanych warunkach błędach, by sprawdzić podczas oceny zwrotu strtol
wraz z kilku różnych warunkach testowych:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int main (int argc, char **argv)
{
if (argc < 2) {
fprintf (stderr, "\n Error: insufficient input. Usage: %s int [int (base)]\n\n", argv[0]);
return 1;
}
const char *nptr = argv[1]; /* string to read */
char *endptr = NULL; /* pointer to additional chars */
int base = (argc > 2) ? atoi (argv[2]) : 10; /* numeric base (default 10) */
long number = 0; /* variable holding return */
/* reset errno to 0 before call */
errno = 0;
/* call to strtol assigning return to number */
number = strtol (nptr, &endptr, base);
/* output original string of characters considered */
printf ("\n string : %s\n base : %d\n endptr : %s\n\n", nptr, base, endptr);
/* test return to number and errno values */
if (nptr == endptr)
printf (" number : %lu invalid (no digits found, 0 returned)\n", number);
else if (errno == ERANGE && number == LONG_MIN)
printf (" number : %lu invalid (underflow occurred)\n", number);
else if (errno == ERANGE && number == LONG_MAX)
printf (" number : %lu invalid (overflow occurred)\n", number);
else if (errno == EINVAL) /* not in all c99 implementations - gcc OK */
printf (" number : %lu invalid (base contains unsupported value)\n", number);
else if (errno != 0 && number == 0)
printf (" number : %lu invalid (unspecified error occurred)\n", number);
else if (errno == 0 && nptr && !*endptr)
printf (" number : %lu valid (and represents all characters read)\n", number);
else if (errno == 0 && nptr && *endptr != 0)
printf (" number : %lu valid (but additional characters remain)\n", number);
printf ("\n");
return 0;
}
Wydajność:
$ ./bin/s2lv 578231
string : 578231
base : 10
endptr :
number : 578231 valid (and represents all characters read)
$ ./bin/s2lv 578231_w_additional_chars
string : 578231_w_additional_chars
base : 10
endptr : _w_additional_chars
number : 578231 valid (but additional characters remain)
$ ./bin/s2lv 578some2more3stuff1
string : 578some2more3stuff1
base : 10
endptr : some2more3stuff1
number : 578 valid (but additional characters remain)
$ ./bin/s2lv 00000000000000000
string : 00000000000000000
base : 10
endptr :
number : 0 valid (and represents all characters read)
$ ./bin/s2lv stuff578231
string : stuff578231
base : 10
endptr : stuff578231
number : 0 invalid (no digits found, 0 returned)
$ ./bin/s2lv 00000000000000000 -2
string : 00000000000000000
base : -2
endptr : (null)
number : 0 invalid (base contains unsupported value)
[C++ - prawidłowe użycie strtol] (http: // StackOverflow. com/questions/14176123/correct-usage-of-strtol) – DOOM