trying to make loop that will reject non integer inputs as well my code works to print invalid input and loop whenever a answer outside of the range is inputted but it will keep looping forever if a non integer is entered, is there any way to program it so that it will print invalid and loop back?
my code:
while(ans < 1 || ans > 4)
{
printf("\n\nEnter the ans: ");
scanf("%f", &ans);
if(ans < 1 || ans > 4)
printf("Invalid Input! Please re-enter value.\n");
}
CodePudding user response:
What data type is 'ans' declared as ? You are reading it with a float format "%f". Then you are comparing ans to ints throughout. If you want to read an int, then use "%d" and declare "int ans;". You should check the return value from scanf to see if any value was parsed.
CodePudding user response:
The loop is problematic as scanf("%f", ans) will consume only character it can interpret as a float then possibly stop before newline. If you type "foo" or ctrl-d at it, it will loop forever. This code will also accept "3.0" or "3foo" or "3.00foo" or "3.00000000000000000000000000000001" as an answer that exits the loop.
To avoid the infinite loop, you really can't use just the scanf("%f" for input - you must examine the entire input line. Things get complex with some decent error checks.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define LINESIZE (80)
int main()
{
float ans;
char line[LINESIZE];
char *fgp, *endpt;
while(1) {
// prompt & read a line
printf("\n\nEnter the ans: ");
fgp = fgets(line, LINESIZE, stdin);
if(fgp == NULL) {
if(feof(stdin)) // EOF, exit cleanly
exit(0);
else { // error, exit dirty
perror("Thisfunction");
exit(42);
}
}
// No EOL: errmsg, skip input, retry
if(line[strlen(line)-1] != '\n') {
printf("ERR: line too long!\n");
// gobble line from input buffer
while(getchar() != '\n')
;
continue;
}
// parse a float
ans = strtof(line, &endpt);
// no conversion: errmg, retry
if(endpt == line) {
printf("ERR: invalid numeric input\n");
continue;
}
// trailing junk: errmg, retry
while(isspace(*endpt))
endpt ;
if(*endpt != '\0') {
printf("ERR: invalid trailing characters\n");
continue;
}
// bad value: msg, retry
if(ans < 1 || ans > 4 || (fmodf(ans, 1.0) != 0.0)) {
printf("Invalid Value! Out of range.\n");
continue;
}
// not an int (sort of). Note this is a poor test.
if((fmodf(ans, 1.0) != 0.0)) {
printf("Invalid Value! Not an integer.\n");
continue;
}
// success
break;
}
// ans should be 1, 2 or 3
printf("exiting, ans = %2.0f\n", ans);
return 0;
}
Example run
$ ./test
Enter the ans: foobar
ERR: invalid numeric input
Enter the ans: 12.foo
ERR: invalid trailing characters
Enter the ans: 5
Invalid Value! Out of range.
Enter the ans: 3.555
Invalid Value! Not an integer.
Enter the ans: 2.00
exiting, ans = 2