Повторить попытку ввода при неверном вводе с клавиатуры - 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
используется для определения символа, следующего за последним символом в строке.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д