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 > 0) || (digits > 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 > 0 ) {
digitsAfterDecimal += 1;
}
}
}
return (decimals > 0) ? ((digits > 0) && (digitsAfterDecimal > 0))
: (digits > 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.
int
s mainly asbool
s, might want to consider to usebool
s there for that. – Bobby Apr 28 at 21:18int
variable you are referring to? The followingint
variables (signs
,decimals
,digits
,digitsAfterDecimal
) are used as counters. – Arun Apr 28 at 21:50decimals
might bebool
calledhasDecimalPoint
,*p == '.' ... if (hasDecimalPoint) return false; hasDecimalPoint = true;
. – Bobby Apr 28 at 22:26