Home > Software engineering >  make a loop reject all non integer inputs and integer inputs outside of range (C programming)
make a loop reject all non integer inputs and integer inputs outside of range (C programming)

Time:07-29

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

 
  •  Tags:  
  • c
  • Related