Помогите реализовать проверку на ввод данных

Хочу сделать функцию чтобы она проверяла диапазон вводимых значений вместе с защитой от дурака, то есть если поле должно хранить числовое значение, то пользователь не мог ввести строковые. Вот какая функция у меня получилась:

int CHECK(int a, int b, int user_number)
{

    while (scanf("%d", &user_number) != 1 || user_number >= a || user_number <= b)
    {
            printf("Ошибка ввода. Попробуйте еще раз\n-> ");
            while (getchar() != '\n');
    }
    return user_number;
}

а вот откуда она будет вызвана:

void ENTER_DATA(struct DATA* notebook)
{
    printf("Введите фамилию -> ");
    scanf("%s", notebook->surname);
    printf("Введите имя -> ");
    scanf("%s", notebook->name);
    printf("Введите отчество -> ");
    scanf("%s", notebook->patronymic);
    printf("Введите дату рождения:\nДень -> ");
    scanf("%u", &notebook->BirthDate);
    CHECK(1,31, notebook->BirthDate);
    printf("Месяц -> ");
    scanf("%u", &notebook->BirthMonth);
    printf("Год -> ");
    scanf("%u", &notebook->BirthYear);
    printf("Введите адрес:\nУлица -> ");
    scanf("%s", notebook->addresSTREET);
    printf("Номер дома -> ");
    scanf("%u", &notebook->addresHOME);
    printf("Введите номер мобильного телефона -> ");
    scanf("%u", &notebook->mobileNUMBER);
}

На данном этапе функция не работает, как задумывалась, она выводит сообщение об ошибке, даже если введенные данные корректны. Подскажите пожалуйста что необходимо исправить чтобы все заработало так как надо.


Ответы (1 шт):

Автор решения: nevilad

Проблема в проверке диапазона в CHECK, его следует проверять так:

while (scanf("%d", &user_number) != 1 || !( user_number >= a && user_number <= b ))

или так:

while (scanf("%d", &user_number) != 1 || user_number < a || user_number > b )

Полагаю ошибочно и то, что день рождения должен вводиться дважды, один раз в строке

scanf("%u", &notebook->BirthDate);

второй раз в CHECK. Непонятно также зачем передавать user_number в CHECK, его значение не используется, а scanf затирает его. CHECK просит повторить ввод пока не будет введено корректное значение, а потом возвращает его. Но вызывающий код игнорирует это значение. Цикл по getchar не нужен. Следовало бы переписать проверку например так:

int CHECK(int a, int b)
{
    int user_number;
    while (scanf("%d", &user_number) != 1 || !( user_number >= a && user_number <= b ))
    {
            printf("Ошибка ввода. Попробуйте еще раз\n-> ");
    }
    return user_number;
}

printf("Введите дату рождения:\nДень -> ");
notebook->BirthDate = CHECK(1,31);
→ Ссылка