Search code examples
cloopsinfinite

Infinite loop issue in c


The code below compiles, however when I run it I have an error that causes an infinite loop. The loop doesn't even get to scanf where I should be taking in the new value instead it just always prints the prompt. What exactly have I done wrong to cause this issue..

#include <stdio.h>
#include <stdbool.h>

//variables
bool flag = false;
int input = 0;
//function protoypes
void  get_input(void);
bool  is_valid(int);
void  print_pattern(int number);

int main(){
    get_input();

    print_pattern(input);
    return 0;
}

void get_input(){
    while(flag == false){
        printf("please enter an odd number betwen 1 and 9\n");
        scanf("%d", &input);
        if(is_valid(input)){
            flag = true;
        }else{
            flag = false;
        }

    }
}

bool is_valid(int number){
    if(number == 1 || number == 3 || number == 5 || number == 7 || number ==  9){
        return true;
    }else{
        return false;
    }
}

void print_pattern(int number){
    int i = 0;
    for(i = 0; i < number; i++){
        printf("%s",i);
    }
}

Solution

  • You have fallen into a scanf trap: When you try to scan a decimal number from a stream (such as a file or stdin), but the stream doesn't contain a valid number, the stream is reset to where it was before the scanning. That means, your while loop scans the same invalid input over and over.

    A solution is to read a string first (with scanf("%s", ...) or with fgets and then parse that string with sscanf or, maybe better, with strtol. All these functions have an error condition, described in their documentation, which you should check. There is also the issue of how to treat the unexpected end of file which you may encounter during input.

    Finally, you should make the flag local to get_input. Also consider get_input to return the read value with a special value, say -1, to indicate end of file.

    An example implementation might look like this.

    int get_input()
    {
        char buf[80];
        int input = 0;
        bool flag = false;
    
        while (flag == false) {
            printf("please enter an odd number betwen 1 and 9\n");
    
            if (fgets(buf, sizeof(buf), stdin) == NULL) return -1;
            flag = (sscanf(buf, "%d", &input) == 1 && is_valid(input));
        }
    
        return input;
    }
    

    (Yes, reading input other than the in a quick-and-dirty way isn't easy.)

    Others have already pointed out the wrong format specifier, which -Wall should have caught.