I've been creating a program requesting the user to input a char value, but if they enter more than one character it will move onto the next function and break the program. I've added in the second method which gets run when multiple inputs are entered.
Your problem is not one of limiting the number of characters written to cInput
; the format specifier %1s
does that already. Your problem is one of leaving unprocessed characters in the input buffer. You need to remove all characters from the buffer if subsequent input will not handle them. For example if you leave a alphabetic character in then buffer but later read with %d
, the function will return immediately (because there is implicitly a newline also buffered), but the character will remain buffered because it is not a decimal. This will continue indefinitely if you never clear the buffer.
For a single character, you can check the character is not a newline, and then repeatedly get characters until a newline is found, as follows:
scanf("%c", &cInput ) ;
while( cInout != '\n' && getchar() != '\n' ) { } // flush buffered line
If you want to be sure the user only enters a single character, then you could modify the above thus:
scanf("%c", &cInput ) ; // Get a single character
if( cInput != '\n' && // If the input is not "empty",
getchar() != '\n' ) // but the first character entered was not
// immediately followed by a newline...
{
// Flush to the end of the entered line
while( getchar() != '\n' ) { }
// Invalidate the input to force retry
cInput = 0 ;
}
At least one character will be buffered - a newline at least. A valid answer will have two characters one in cInput
and a newline. The if(...)
condition above reads the second character if there is one (using short-circuit evaluation of cInput
), and checks that it is the end of the input (newline). If it is not, it reads all buffered characters then invalidates cInput
(in case say "No-way\n"
were entered for example, so that cinput
contained 'N'
.
For numeric input, you simply read characters until the newline is found:
scanf("%d", &nValue);
while( getchar() != '\n' ) { } // flush buffered line
If trailing non-numeric characters should render the entire input invalid, you need to check that the following character is a newline.
int converted = scanf("%d", &nValue);
if( converted == 0 || getchar() != '\n' )
{
valid_input = false ;
while( getchar() != '\n' ) { } // flush buffered line
}
Note that there are other possible solutions. This is my preferred solution.
When applied to your functions (with other simplifications):
int intAskUser(void)
{
char cInput = 0 ;
while( cInput != 'N' && cInput != 'Y' )
{
printf("Do you want to enter a value? Y or N\n");
scanf("%c", &cInput ) ;
if( cInput != '\n' && getchar() != '\n' )
{
while( getchar() != '\n' ) { } // flush buffered line
cInput = 0 ;
}
else
{
cInput = toupper(cInput) ;
}
}
// Return answer code 0 to 1
return (cInput == 'N') ? 0 : 1 ;
}
int getValue(int nLower, int nUpper)
{
assert( nLower < nUpper ) ; // precondition check
int nValue = 0 ;
bool valid_input = false ;
while( !valid_input )
{
printf("Enter a value between %d and %d: ", nLower, nUpper ) ;
int converted = scanf("%d", &nValue);
if( converted == 0 || getchar() != '\n' )
{
valid_input = false ;
while( getchar() != '\n' ) { } // flush buffered line
}
valid_input = nValue >= nLower &&
nValue <= nUpper ;
if( !valid_input )
{
printf( "Please try again. " );
}
}
printf("Value: %d", nValue);
return nValue;
}
Note that toupper()
requires ctype.h
to be included, and the type bool
requires stdbool.h
.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments