Reputation: 135
My C code as follows
int main() {
int userInput = 0;
while (userInput != 4) {
printf("Enter a number : ");
scanf("%d", &userInput);
};
return 0;
}
This normally work when input a integer value. But when input a string value it not asking again to a input. It goes to a endless loop printing the "Enter a number" phrase. Then, I tried the code as follows.
int main() {
int userInput = 0;
while (userInput != 4) {
userInput = 0; // reset the userInput value
printf("Enter a number : ");
scanf("%d", &userInput);
};
return 0;
}
Even that not solved my problem. Why is this happening? How can it be fixed?
Upvotes: 3
Views: 1066
Reputation: 23208
"This normally work when input a integer value. But when input a string value it not asking again to a input."
If a data scan is not converted by scanf()
, the input stream, in this case stdin
, is not advanced. When scanf()
is called again, it will attempt to scan & convert the same data from the same incorrect input, with the same result. This is what causes your infinite loop. Inputting alpha characters when `scanf() is setup to convert numeric characters will always fail.
The good news is scanf() returns a value indicating how many items were converted successfully. alpha input scanned using the %d
format specifier, should result in converting zero items. Code using scanf()
should always check it's return value:
int num_converted = scanf("%d", &userInput);
if(num_converted != 1)
{
//handle error
...
}
As an aside, scanf()
is considered by many as as sub-optimal method for handling user input. For example
"...it will tell you whether it succeeded or failed, but can tell you only approximately where it failed, and not at all how or why. You have very little opportunity to do any error recovery."
(jamesdlin).
Consider an alternative method based on using fgets()
.
The following reads the entire input line into a buffer, eliminates unwanted white space and validates input. Only then does it convert the input buffer to the specified type...
int main(void) {
int userInput = 0;
char inBuf[20] = {0};
printf("Enter a number : ");
//int num = scanf("%d", &userInput);
while (fgets(inBuf, sizeof inBuf, stdin)) {
inBuf[strcspn(inBuf, "\r\n")] = 0;//remove unwanted white space
if(digits_only(inBuf))//example validation for numeric only input
{
userInput = atoi(inBuf);
printf("\n%d entered, and converted!\n\nctrl-c to exit\n...Or enter a number : \n", userInput);
}
else
{
printf("\n%s contains non-numeric characters, it cannot be converted.\n\nctrl-c to exit\n...Or enter a number : \n", inBuf);
}
};
return 0;
}
//test for numeric only input
//(note that other validations can be coded with expansions
//to accommodate float or double, alpha only, etc.)
bool digits_only(const char *in)
{
while(*in)
{
if(!isdigit(*in)) return false;
in++;
}
return true;
}
Upvotes: 1
Reputation: 310930
You need to free the input buffer from an invalid data. Something like the following.
do
{
printf("Enter a number : ");
if ( scanf("%d", &userInput) != 1 )
{
scanf( "%*[^\n]" );
userInput = 0;
}
} while ( userInput != 4 );
Another approach is to use the function fgets
to read the whole string in a character array and then convert it to an integer using strtol
and check whether the conversion was successful.
Upvotes: 1