If the input should be a single number on the line, then:
char line[4096];
int x;
if (fgets(line, sizeof(line), stdin) == 0)
...EOF or other major trouble...
else if (sscanf(line, "%d", &x) != 1)
...not an integer...
else if (x < 0)
...negative - not allowed...
else if (x > 4)
...too large - maximum is 4...
else
...Hooray - number is valid in the range 0-4...use it...
You get to choose how the errors are handled. The first error handling should abandon the efforts to get a number from the user; the other three could warrant a retry (but keep an eye on how many retries you allow; if they get it wrong 10 times in a row, it is probably time to give up).
The key point is that the code uses fgets() to get the whole line, and then parses that. It would be possible to do further analysis — to make sure there isn't extra information on the line (so the user didn't type '3 dogs' instead of just '3'). This also allows you to report errors in terms of the whole line. The test for if (sscanf(line, "%d", &x) != 1) is also important. The members of the scanf()-family of functions report the number of successful conversion specifications (%d is a conversion specification). Here, if sscanf() successfully converts an integer, it will return 1; otherwise, it may return 0 or EOF (though EOF is unlikely with sscanf()). If there were 3 conversion specifications, the correct check would be != 3; it might report 1 or 2 successful conversions.