#include <cassert>
#include <cctype>
// true if positive or negative number including decimal points
// 42
// 42.56
// +42
// -42
// false otherwise
// 42. --> false
// ++42
// +.
// 4+
// regexp := [+|-][d+][.][d+]
// start -> sign -> digit -> decimal -> digit
// reject
bool isnumeric( char const * );
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) ;
}
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();
}