Test if string is numeric I want to implement the following function:

// Return true if and only if 's' is numeric including
// leading positive/negative sign, decimal point.
bool isnumeric( const char * s );


It is somewhat similar to strtol() but I don't need to return the number.

My approach is to count various things unless I can bail out:

bool isnumeric( char const * str ) {
  if( !str ) { return false; }
  int signs = 0;
  int decimals = 0;
  int digits = 0;
  int digitsAfterDecimal = 0;

  for( char const * p = str; *p; ++p ) {

    if( (*p == '+') || (*p == '-') ) {
      if( (decimals &gt; 0) || (digits &gt; 0) ) { return false; }
      signs += 1;
      if( signs == 2 ) { return false; }
    }
    else if( *p == '.' ) {
      decimals += 1;
      if( decimals == 2 ) { return false; }
    }
    else if( ! isdigit( *p ) ) { 
      return false;
    }
    else {
      digits += 1;
      if( decimals &gt; 0 ) {
        digitsAfterDecimal += 1;
      }
    }
  }
  return (decimals &gt; 0) ? ((digits &gt; 0) &amp;&amp; (digitsAfterDecimal &gt; 0))
                        : (digits &gt; 0) ;
}


I also have the following tests:

void test_isnumeric() {
  assert( isnumeric( "42" ) );
  assert( isnumeric( "42.0" ) );
  assert( isnumeric( "42.56" ) );
  assert( isnumeric( "+42" ) );
  assert( isnumeric( ".42" ) );
  assert( isnumeric( "+.42" ) );

  assert( ! isnumeric( "42." ) );
  assert( ! isnumeric( "++42" ) );
  assert( ! isnumeric( "+." ) );
  assert( ! isnumeric( "4+" ) );
}

int main( void ) {
  test_isnumeric();
}


To make it easy to clone and modify, the full code is available here.

Please comment on design, structuring, test coverage etc. Mentioning failing tests are most welcome.
State variables are bad. Keep the state explicit, along the lines of:

if (*p == '+' || *p == '-') p++;
if (!isdigit(*p)) return False;
while (isdigit(*p)) p++;
if (*p == 0) return True;
if (*p != '.') return False;
p++;
while (isdigit(*p)) p++;
return *p == 0;


Update: few fixes thanks to Edward