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);
}
}
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.