Ответы других, особенно @ John Bollinger , хорошо объясняют, почему код не соответствует цели.
Примечание: вход может преобразовывать в int
, float
, ни то, ни другое, или оба.
Как я могу сделать ввод строгим со стандартными функциями и выдать исключение, если не было ни целых чисел, ни числа с плавающей запятой?
Лучше всего использовать другие инструменты, такие как fgets()
, чтобы прочитать строку ввода и сформировать строку для последующего тестирования.
Проверить строго довольно сложно. *scanf("%d",...)
имеет неопределенное поведение при переполнении. *scanf("%f",...)
имеет аналогичный UB, особенно когда float
не поддерживает бесконечность / не число.
Чтобы проверить, преобразована ли строка в допустимое значение int
bool my_isint(const char *s) {
// Add to dis-allow leading white-space
if (isspace((unsigned char) *s)) return false;
char *endptr;
base = 0; // use base = 0 to only allow base 10 input
errno = 0;
long val = strtol(s, &endptr, base);
if (s == endptr) return false; // no conversion
if (errno == ERANGE) return false; // too big for long
if (val > INT_MAX || val < INT_MIN) return false; // too big for int
// Add to allow trailing white-space
while (isspace((unsigned char) *endptr)) endptr++;
// Add to dis-allow trailing junk
while (*endptr) return false; // trailing junk
return true;
}
Проверка того, преобразуется ли строка в допустимое значение float
, похоже на проверку double
, когда float
поддерживает бесконечность / не-число. Еще позже - ГТГ.