-
scanf ?
How do I catch bad input in scanf()? For example, if scanf is expecting integer but the user types in alpha, the program continues with last good integer input. In C++ I used a combo of cin.good, cin.clear and cin.ignore. The while (getchar() != '\n'); works for clearing out stream but how do i test for input data not matching expected data type?
-
I dont think that you can with scanf() although if I'm wrong salem will correct me but I believe a better strategy would be to use fgets() and get all input as a string and then validate the string using isalpha(),or isdigit() etc. then if you need an int or a double you can pass the validated string to atoi() or atof(). You could also use sscanf() on the buffer filled by fgets() but i guess it just boils down to not using scanf().
-
Like Stoned_Coder said :)
scanf returns a lot of potential status results which you have to consider, and take action on each one.
The fgets() approach has the following advantages
1. it separates the EOF test from the conversion results, so your test of the success of sscanf() only has to worry about success/fail of the conversion.
2. if you don't like the buffer, fgets() will have already read upto the next \n, so the input stream is always tidy. You just re-use the buffer in the next fgets() call.
3. you can have several attempts at deciding what a buffer means, should it be necessary (eg. enter a number, or 'q' to quit).
4. when it comes to reading in strings using %s, it becomes more tricky to prevent accidental buffer overflow possibilities.
Some code
Code:
#include <stdio.h>
void use_scanf ( ) {
int i, res;
printf( "Enter number\n" );
res = scanf( "%d", &i );
if ( res == 1 ) {
// success
printf( "Congrats, you entered %d\n", i );
} else
if ( res == 0 ) {
// failed, purge input
// this should also check for EOF
printf( "Junking bad input\n" );
while ( getchar() != '\n' );
} else {
// EOF to start with
printf( "Found EOF\n" );
}
}
void use_fgets ( ) {
char buff[BUFSIZ];
int i, res;
printf( "Enter number\n" );
if ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
res = sscanf( buff, "%d", &i );
if ( res == 1 ) {
// success
printf( "Congrats, you entered %d\n", i );
} else {
// failed, just ignore the buffer
printf( "Ignoring bad input\n" );
}
} else {
// EOF to start with
printf( "Found EOF\n" );
}
}
int main() {
// choose one
// use_scanf();
use_fgets();
return 0;
}
-
Code:
While ( scanf("%d",&num) != 1 || num > 32000 || num < 0)
{
printf("Try again: ");
while( getchar() != '\n') continue;
}
Works something like that. You can set the range as long as it is in the rage of the built in type.
-
Thanks again! this board is great!...your time is greatly appreciated.