FAQ > Validate user input


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > How do I... (Level 2) > Validate user input

This item was added on: 2003/03/22

Validate user input

It depends on what you're validating and for what purpose. The simplest way to validate input is to use fgets to read an entire line and then use sscanf to parse it. If sscanf fails the input is not valid:


#include <stdio.h> 
#include <stdlib.h> 

/*
 * Expect a line containing
 *   <int> <double> <6 char string>
 */
int main ( void )
{
  char buff[BUFSIZ];
  char s[7] = {0}; /* +1 for nul */
  double f;
  int n;

  if ( fgets ( buff, sizeof buff, stdin ) != NULL ) {
    if ( sscanf ( buff, "%d %lf %6c", &n, &f, s ) != 3 ) {
      fprintf ( stderr, "Invalid input\n" );
      exit ( EXIT_FAILURE );
    }

    printf ( "%d:\n\t%s -- %f\n", n, s, f );
  }

  return 0;
}


Naturally this will not work perfectly for all input. For example, if you wanted to make sure that the 6 character string was indeed 6 characters or that the values were in a specific range, you would have to do this manually:


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/*
 * Expect a line containing
 *   <int> <double> <6 char string>
 */
typedef enum boolean { BFALSE, BTRUE } bool_t;

static void die ( char *msg )
{
  fprintf ( stderr, "%s\n", msg );
  exit ( EXIT_FAILURE );
}

static bool_t valid_data ( int n, double f, char *s )
{
  if ( strlen ( s ) != 6 || n < 100 || n > 999 || f < 1.0 || f > 100.0 )
    return BFALSE;

  return BTRUE;
}

int main ( void )
{
  char buff[BUFSIZ];
  static char s[7]; /* +1 for nul */
  double f;
  int n;

  if ( fgets ( buff, sizeof buff, stdin ) != NULL ) {
    if ( sscanf ( buff, "%d %lf %6c", &n, &f, s ) != 3 )
      die ( "Invalid input" );

    if ( valid_data ( n, f, s ) != BFALSE )
      printf ( "%d:\n\t%s -- %f\n", n, s, f );
    else
      die ( "Invalid input" );
  }

  return 0;
}


For less structured data, such as a simple integer, you can use scanf:


#include <stdio.h> 
#include <stdlib.h> 

static void die ( char *msg )
{
  fprintf ( stderr, "%s\n", msg );
  exit ( EXIT_FAILURE );
}

int main ( void )
{
  int num;

  printf ( "Enter an integer: " );

  if ( scanf ( "%d", &num ) != 1 )
    die ( "Invalid input" );

  printf ( "Your number was: %d\n", num );

  return EXIT_SUCCESS;
}


Or a more thorough approach with fgets and strtol:


#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

typedef enum boolean { BFALSE, BTRUE } bool_t;

static void die ( char *msg )
{
  fprintf ( stderr, "%s\n", msg );
  exit ( EXIT_FAILURE );
}

static bool_t get_int ( int *ival )
{
  char buff[25];
  long lval;
  char *end;

  if ( fgets ( buff, sizeof buff, stdin ) == NULL )
    return BFALSE;

  lval = strtol ( buff, &end, 10 );

  if ( lval < INT_MIN || INT_MAX < lval || end == buff )
    return BFALSE;

  *ival = (int)lval;

  return BTRUE;
}

int main ( void )
{
  int num;

  printf ( "Enter an integer: " );

  if ( get_int ( &num ) != BFALSE )
    printf ( "Your number was: %d\n", num );
  else
    die ( "Invalid integer" );

  return EXIT_SUCCESS;
}


Every one of these techniques can be modified to perform weaker or stronger checking, or specialized validation as required. Note that these are not the only ways to validate input, they just tend to be the simplest.

Credit: Prelude

Script provided by SmartCGIs