When dealing with line-based user input, it makes sense to always read one line at a time. This is not what the function scanf does. For example, if you use the "%s %d %d" format string, then scanf will continue reading input until it is able to match both numbers, or until it encounters a character that makes the match impossible (such as an alphabetical character). It will continue reading input past the end of the line if the user enters "quit" without entering two numbers on the same line, which is probably not what you want.
For reading exactly one line of input, I recommend that you use the function fgets. You can then, if you want, use sscanf on that single line of input. That way, you won't have the problem of your program attempting to read more than one line of input. The function sscanf will simply report that it was only able to match the first specifier, if the user does not enter any numbers afterwards.
With the functions scanf and sscanf, you can check the return value of the function to determine how many specifiers in the format string were matched.
It is unsafe to use the result of scanf or sscanf without first checking the return value of that function, in order to determine how many arguments were matched. Otherwise, you may be using a non-existant result. See this guide for further information:
A beginners' guide away from scanf()
Also, when using the %s format specifier in scanf or sscanf (but not printf), it is generally a good idea to limit the number of characters written. Otherwise, a buffer overflow will occur if the user enters more than 9 characters (10 characters including the terminating null character), because the array str only has room for 10 characters. A buffer overflow should always be prevented, because it can cause bugs that are very hard to find.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sum( const int a, const int b )
{
printf( "The sum of %d and %d is %d.\n", a, b, a + b );
}
void quit()
{
printf( "Quitting.\n" );
exit( EXIT_SUCCESS );
}
int main( void )
{
char line[100];
char str[10];
int x, y;
int num_matched;
printf( "Call a function: " );
if ( fgets( line, sizeof line, stdin ) == NULL )
{
fprintf( stderr, "Input error!\n" );
exit( EXIT_FAILURE );
}
num_matched = sscanf( line, "%9s %d %d", str, &x, &y );
if ( num_matched >= 1 && strcmp( str, "quit" ) == 0 )
quit();
else if ( num_matched >= 3 && strcmp( str, "sum" ) == 0 )
sum( x, y );
else
printf( "Bad input!\n" );
}
This program has the following behavior:
Call a function: sum 5
Bad input!
Call a function: sum 5 7
The sum of 5 and 7 is 12.
Call a function: quit
Quitting.
getlineis in all reasonable C libraries already; if not, it's a couple line wrapper forfgets), then possibly usingsscanforstrtok_ror something to parse within the line.