So I'm trying making a simple menu to a program that only accepts the options 1,2 and 3 and I want to control the user input to prevent errors like when the user inputs char instead of int.
Right now it controls some cases like if the option is less than 1 or greater than 3, if the option is a char it also does not affect but when the user inputs something like " 02" or "2a" it runs option 2 but should invalidate that option.
Also if there´s more cases that I'm missing I would like to know them and how to overcome them.
#include <stdio.h>
#include <stdlib.h>
void empty_stdin(void);
int main() {
int option;
int rtn;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
rtn = scanf("%d", &option);
if (rtn == 0 || option < 1 || option > 3) {
printf("-Invalid Option-\n");
empty_stdin();
} else {
empty_stdin();
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
}
} while (option != 3);
return 0;
}
void empty_stdin(void) {
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
Example Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Expected Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Consider using fgets
to capture input and strtol
to parse an integer.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int fgetsint ( int *value, int min, int max, FILE *fin) {
char line[100] = "";
char extra = '\0';
char *end = NULL;
long int number = 0;
if ( fgets ( line, sizeof line, fin)) {//read a line
errno = 0;
number = strtol ( line, &end, 10);
if ( end == line) {// nothing was parsed. no digits
printf ( "input [%s] MUST be a number\n", line);
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
perror ( "input error");
return 0;
}
if ( 1 == sscanf ( end, " %c", &extra)) {//parse trailing character
printf ( "enter one number only. try again\n");
return 0;
}
if ( number > max || number < min) {
printf ( "Input [%ld] out of range: min: %d max: %d\n", number, min, max);
return 0;
}
if ( 1 != (int)( end - line)) {
printf ( "input one digit\n");
return 0;// return failure
}
*value = number;//assign number to pointer
}
else {
fprintf ( stderr, "problem fgets\n");
exit ( EXIT_FAILURE);
}
return 1;//success
}
int main ( void) {
int option = 0;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
option = 0;
fgetsint ( &option, 1, 3, stdin);
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
} while ( option != 3);
return 0;
}