Well i have this code to find the paint quality of a room.
void get_room_size(char room_id, int * length, int * width) {
while (*length <= 0 && *width <= 0) {
printf("Enter length and width of room %c in feet: ", room_id);
if (scanf("%d,%d", length, width)) {
if (*length <= 0) {
printf("###Error! Length must be a positive value!\n");
}
if (*width <= 0) {
printf("###Error! Width must be a positive value!\n");
}
printf("\n");
} else {
printf("bad data");
*length = 0;
*width = 0;
}
}
}
Basically, if i enter
a,1
It will go crazy and keep looping. Whats the problem?
The reason it’s going “crazy” is as follows. When
scanffails to read inaas a number (because it’s not numeric, obviously), it won’t advance the file pointer.This is one reason why you shouldn’t generally use
scanfoperations, a failure can leave the file pointer in an indeterminate position (such as if you only scan in 3 of 12 items).Anyway, back to the failure. Because the file pointer isn’t advanced, the next time you come back to do
fscanf, it will try to read thataagain (and again and again).If you want a decent function for handling user input, look no further than here:
This will input a line from the user, with overflow protection (unlike
getsorscanfwith unbounded"%s").It also flushes to end of line if the input was too long, which will stop the remainder of the line from affecting the next input operation.
You can then
sscanfthe buffer to your heart’s content without any concerns re the file pointer.The following test program shows how to use this:
As an aside, you may want to re-examine your logic for a valid sized room. What you currently have would allow a room to be entered as 7 by -42 feet 🙂
It’s also not usually good form to rely on the output values being set to specific values on entry. If length and width are (for example) 3 and 4 on entry, this function will exit straight away without asking the user for input.
The first problem can be fixed by using
||instead of&&. The second by initialising the variables to 0 at the start of the function so that the loop is entered.For completeness, if you combine that original snippet above (the
includestatements and thegetLine()function) with the following slightly modifiedget_room_size()function:and the very simple test
main(), you’ll see a complete program showing how to do it.