Повторить попытку ввода при неверном вводе с клавиатуры - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. С клавиатуры вводятся элементы массива типом float. При ошибочном вводе, например при вводе символов или букв вместо элемента массива - программа выдает ошибку. Можно ли сделать так, чтобы при неверном вводе программа запросила повторный ввод? Желательно повторный ввод именно с того элемента, на котором возникла ошибка, но если это сложно реализуема - можно начинать ввод с самого начала. Нашел аункцию try, catch, throw, но как мне обьяснили классы в СИ не поддерживаются.

Решение задачи: «Повторить попытку ввода при неверном вводе с клавиатуры»

textual
Листинг программы
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
 
#define CLI_BUFFER_SIZE 256
 
float get_float(void) 
{
    char *end;
    char buff[CLI_BUFFER_SIZE] = "";
 
    while (1) {
        if (!fgets(buff, CLI_BUFFER_SIZE, stdin))
            continue;
        buff[strcspn(buff, "\n")] = '\0';
        
        buff[strcspn(buff, ",")] = '.'; // а вообще числа с плав точкой вводят вроде как через точку =)
 
        errno = 0;
        float sl = strtof(buff, &end);
 
        if (*buff == '\0') { 
            fprintf(stderr, "empty string\n");
        } else if ((HUGE_VALF == sl || HUGE_VALF == sl) && ERANGE == errno) {
            fprintf(stderr, "out of range of type float\n");
        } else if ('\0' != *end) {
            fprintf(stderr, "extra characters\n");
            fprintf(stderr, "\t%s\n" , buff);
            fprintf(stderr, "\t%*c\n", (int)(end - buff) + 1, '^');
        } else {
            return (float)sl;
        }
        fflush(stdin);
    }
}
 
int get_int(void) 
{
    char *end;
    char buff[CLI_BUFFER_SIZE] = "";
 
    while (1) {
        if (!fgets(buff, CLI_BUFFER_SIZE, stdin))
            continue;
        buff[strcspn(buff, "\n")] = '\0';
        
        errno = 0;
        long sl = strtol(buff, &end, 10);
 
        if (*buff == '\0') {
            fprintf(stderr, "empty string\n");
        } else if ((LONG_MIN == sl || LONG_MAX == sl) && ERANGE == errno) {
            fprintf(stderr, "out of range of type long\n");
        } else if (sl > INT_MAX) {
            fprintf(stderr, "%ld greater than INT_MAX\n", sl);
        } else if (sl < INT_MIN) {
            fprintf(stderr, "%ld less than INT_MIN\n", sl);
        } else if ('\0' != *end) {
            fprintf(stderr, "extra characters\n");
            fprintf(stderr, "\t%s\n" , buff);
            fprintf(stderr, "\t%*c\n", (int)(end - buff) + 1, '^');
        } else {
            return (int)sl;
        }
        fflush(stdin);
    }
}
 
int main(void)
{
    printf("a: %d\n", get_int());
    printf("a: %f\n", get_float());
    return 0;
}

Объяснение кода листинга программы

  1. В функции get_float и get_int используется цикл while(1), который продолжается до тех пор, пока условие не будет выполнено.
  2. Внутри цикла используется функция fgets для чтения строки из стандартного ввода.
  3. Если строка пустая, выводится сообщение об ошибке empty string.
  4. Если введенное значение выходит за пределы диапазона для типа float или long, выводится сообщение об ошибке out of range of type float или out of range of type long соответственно.
  5. Если после успешного преобразования значения в float или long остаются дополнительные символы, выводится сообщение об ошибке extra characters.
  6. Если введенная строка не может быть преобразована в float или long, выводится сообщение об ошибке invalid conversion.
  7. Если введенное значение больше INT_MAX или меньше INT_MIN, выводится сообщение об ошибке number greater than INT_MAX или number less than INT_MIN соответственно.
  8. Если введенная строка не может быть преобразована в int, выводится сообщение об ошибке invalid conversion.
  9. Значения CLI_BUFFER_SIZE, HUGE_VALF, LONG_MIN, LONG_MAX, INT_MAX и INT_MIN определены в стандартных заголовочных файлах.
  10. Значение ERANGE является константой, определенной в стандартном заголовочном файле <errno.h>.
  11. Функция fflush используется для очистки буфера стандартного ввода.
  12. Функция strcspn используется для определения количества символов в строке до первого вхождения символа новой строки.
  13. Функция strtol используется для преобразования строки в long.
  14. Функция strtof используется для преобразования строки в float.
  15. Функция fprintf используется для вывода сообщений об ошибках в стандартное средство вывода ошибок.
  16. Функция printf используется для вывода значений в стандартное средство вывода.
  17. Значения *end и buff[strcspn(buff,\n)] используются для определения позиции символа новой строки в строке.
  18. Значение *end используется для определения позиции последнего символа в строке.
  19. Значение *buff используется для определения первого символа в строке.
  20. Значение *buff используется для определения символа, следующего за последним символом в строке.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.929 из 5
Похожие ответы