debugcMinor
Test if string is numeric
Viewed 0 times
stringtestnumeric
Problem
I want to implement the following function:
It is somewhat similar to
My approach is to count various things unless I can bail out:
I also have the following tests:
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.
// 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.
Solution
State variables are bad. Keep the state explicit, along the lines of:
Update: few fixes thanks to Edward
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
Code Snippets
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;Context
StackExchange Code Review Q#48438, answer score: 4
Revisions (0)
No revisions yet.