Повторить попытку ввода при неверном вводе с клавиатуры - 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; }
Объяснение кода листинга программы
- В функции
get_float
иget_int
используется цикл while(1), который продолжается до тех пор, пока условие не будет выполнено. - Внутри цикла используется функция
fgets
для чтения строки из стандартного ввода. - Если строка пустая, выводится сообщение об ошибке
empty string
. - Если введенное значение выходит за пределы диапазона для типа
float
илиlong
, выводится сообщение об ошибкеout of range of type float
илиout of range of type long
соответственно. - Если после успешного преобразования значения в
float
илиlong
остаются дополнительные символы, выводится сообщение об ошибкеextra characters
. - Если введенная строка не может быть преобразована в
float
илиlong
, выводится сообщение об ошибкеinvalid conversion
. - Если введенное значение больше
INT_MAX
или меньшеINT_MIN
, выводится сообщение об ошибкеnumber greater than INT_MAX
илиnumber less than INT_MIN
соответственно. - Если введенная строка не может быть преобразована в
int
, выводится сообщение об ошибкеinvalid conversion
. - Значения
CLI_BUFFER_SIZE
,HUGE_VALF
,LONG_MIN
,LONG_MAX
,INT_MAX
иINT_MIN
определены в стандартных заголовочных файлах. - Значение
ERANGE
является константой, определенной в стандартном заголовочном файле<errno.h>
. - Функция
fflush
используется для очистки буфера стандартного ввода. - Функция
strcspn
используется для определения количества символов в строке до первого вхождения символа новой строки. - Функция
strtol
используется для преобразования строки вlong
. - Функция
strtof
используется для преобразования строки вfloat
. - Функция
fprintf
используется для вывода сообщений об ошибках в стандартное средство вывода ошибок. - Функция
printf
используется для вывода значений в стандартное средство вывода. - Значения
*end
иbuff[strcspn(buff,
\n)]
используются для определения позиции символа новой строки в строке. - Значение
*end
используется для определения позиции последнего символа в строке. - Значение
*buff
используется для определения первого символа в строке. - Значение
*buff
используется для определения символа, следующего за последним символом в строке.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д