У меня есть функция, которая должна получить число от stdin
.Он должен проверять, является ли это действительное число, и при желании установить его в определенном диапазоне.Если ввод достаточно длинный (скажем, 10 символов), то функция печатает сообщение об ошибке и сбрасывает цикл, все работает как задумано.Однако если я введу что-то нелепо длинное, например:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
, тогда что-то пойдет не такЦикл продолжает сбрасываться, но независимо от того, что я набираю, он больше не принимает его, даже если он будет полностью действительным.
Полагаю, это может быть из-за переполнения stdin
?Но не в этом ли смысл fgets()
- он читает только определенное количество символов и отбрасывает все остальное?Как обойти это без использования исключений?
Рассматриваемая функция:
int safeinp(int * num, const char *message, int low, int high)
{
long a;
char buf[11]; // 9 digits for the number + "\n\0"
int success; // flag for successful conversion
do
{
puts(message);
if (!fgets(buf, 11, stdin))
{
fprintf(stderr, "Unagle to obtain input.\n");
return 1;
}
// have some input, convert it to integer:
char *endptr;
a = strtol(buf, &endptr, 12);
if (errno == ERANGE)
{
//this if() right here is what gets executed endlessly if the input is bad
fprintf(stderr, "Invalid number.\n");
success = 0;
}
else if (endptr == buf)
{
fprintf(stderr, "Invalid input.\n");
success = 0;
}
else if (*endptr && *endptr != '\n')
{
fprintf(stderr, "Conversion error.\n");
success = 0;
}
else
{
success = 1;
if (low != high) {
a = (a < low) ? fprintf(stderr, "Input has been adjusted to fit the bounds.\n"), low : a;
a = (a > high) ? fprintf(stderr, "Input has been adjusted to fit the bounds.\n"), high : a;
}
*num = a;
}
} while (!success);
return success;
}
Проблема возникает в Visual Studio 2017 для Windows 10.