I have this program:
#include <stdio.h>
int main(){
int val;
printf("Enter any number: ");
scanf("%d",&val);
printf("The number incremented is %d\n",val+1);
printf("Enter any number again: ");
scanf("%d",&val);
printf("The number decremented is: %d\n",val-1);
return 0;
}
It works completely fine if i give it an integer input, but when its a different input, the program goes crazy and runs without accepting the second input. (the second output is -1). is there a fix to this?
I have tried to test the program with number and non-number inputs, For the non number one in the first input, as the description said, the program continued and didnt accept the second input.
Edit: I did not mention the desired output of the program, sorry about that. If the output is non-integer then it will return with err code 1.
If you want the function to return -1;
in the case of the user entering invalid input, then you should check the return value of scanf
, for example like this:
#include <stdio.h>
int main( void )
{
int val;
printf( "Enter any number: ");
if ( scanf( "%d", &val ) != 1 )
{
printf( "Invalid input!\n" );
return -1;
}
printf( "The number incremented is %d\n", val+1 );
printf( "Enter any number again: " );
if ( scanf( "%d", &val ) != 1 )
{
printf( "Invalid input!\n" );
return -1;
}
printf( "The number decremented is: %d\n", val-1 );
return 0;
}
This program has the following behavior:
Enter any number: abc
Invalid input!
Enter any number: 5
The number incremented is 6
Enter any number again: abc
Invalid input!
Enter any number: 5
The number incremented is 6
Enter any number again: 10
The number decremented is: 9
However, this solution is not perfect. For example, if the user enters 5abc
in the first line, then the first scanf
successfully reads 5
, but the second scanf
will fail:
Enter any number: 5abc
The number incremented is 6
Enter any number again: Invalid input!
If you don't want this counter-intuitive behavior, then it would probably be best not to use the function scanf
for line-based user input, but to rather use the functions fgets
and strtol
instead, for example like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
int get_int_from_user( const char *prompt );
int main( void )
{
int val;
val = get_int_from_user( "Enter any number: ");
printf( "The number incremented is %d\n", val+1 );
val = get_int_from_user( "Enter any number again: ");
printf( "The number decremented is: %d\n", val-1 );
return 0;
}
int get_int_from_user( const char *prompt )
{
//loop forever until user enters a valid number
for (;;)
{
char buffer[1024], *p;
long l;
//prompt user for input
fputs( prompt, stdout );
//get one line of input from input stream
if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
{
fprintf( stderr, "Unrecoverable input error!\n" );
exit( EXIT_FAILURE );
}
//make sure that entire line was read in (i.e. that
//the buffer was not too small)
if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )
{
int c;
printf( "Line input was too long!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
fprintf( stderr, "Unrecoverable error reading from input!\n" );
exit( EXIT_FAILURE );
}
} while ( c != '\n' );
continue;
}
//attempt to convert string to number
errno = 0;
l = strtol( buffer, &p, 10 );
if ( p == buffer )
{
printf( "Error converting string to number!\n" );
continue;
}
//make sure that number is representable as an "int"
if ( errno == ERANGE || l < INT_MIN || l > INT_MAX )
{
printf( "Number out of range error!\n" );
continue;
}
//make sure that remainder of line contains only whitespace,
//so that input such as "6sdfj23jlj" gets rejected
for ( ; *p != '\0'; p++ )
{
if ( !isspace( (unsigned char)*p ) )
{
printf( "Unexpected input encountered!\n" );
//cannot use `continue` here, because that would go to
//the next iteration of the innermost loop, but we
//want to go to the next iteration of the outer loop
goto continue_outer_loop;
}
}
return l;
continue_outer_loop:
continue;
}
}
This program has the following behavior:
Enter any number: 5abc
Unexpected input encountered!
Enter any number: abc
Error converting string to number!
Enter any number: 5
The number incremented is 6
Enter any number again: 10
The number decremented is: 9
Note that my second program is more sophisticated than the first program, because it keeps on prompting the user for input until the user enters a valid int
, whereas the first program simply prints an error message and returns -1
.
I took the function get_int_from_user
from this answer of mine to another question. See that answer for more information on the extensive input validation that the function performs.