Как проверить строку, которая является числом для >INT_MAX
или <INT_MIN
...
, чтобы проверить, находится ли полученный параметр в диапазоне [INT_MIN, INT_MAX]
«приведение строки к числу» и «приведение числа к строке» не будут работать как int
тест. Код должен преобразовать .
long int strtol(const char *nptr, char **endptr, int base)
с готовностью делает это. @ PSkocik
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
bool test_int(const char *s, int *int_result) {
char *endptr; // Location where conversion stopped
errno = 0; // Need to clear, to test for overflow later
long n = strtol(s, &endptr, 0);
if (errno == ERANGE) {
return false; // Outside long range
}
// In case int is narrower than long
#if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
if (n < INT_MIN || n > INT_MAX) {
return false; // Outside int range
}
#endif
if (s == endptr) {
return false; // No conversion
}
// Perhaps allow trailing white-space?
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*endptr != '\0') {
return false; // Extra junk at the end
}
*int_result = (int) n;
return true;
}
В качестве составной части синтаксического анализатора протокола с различными целыми числами ранжирования рассмотрим тест общего назначения подписанный :
bool test_integer(const char *s, intmax_t *integer, intmax_t mn, intmax_t mx) {
char *endptr;
errno = 0;
*integer = strtoimax(s, &endptr, 0);
if (errno == ERANGE || *integer < mn || *integer > mx) {
*integer = (*integer < mn) ? mn : mx;
errno == ERANGE;
return false; // Outside intmax_t range
}
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (s == endptr || *endptr != '\0') {
return false; // No conversion or junk at end
}
return true;
}
// Sample usage for int
intmax_t im;
if (test_integer(s, &im, INT_MIN, INT_MAX)) {
int i = (int) im;
...