Re: any STL/string function available for determing string contains numeric
On Apr 4, 5:40 pm, Jacek Dziedzic
<jacek.dziedzic.n.o.s.p....@gmail.com> wrote:
verdverm wrote:
On Apr 4, 12:22 am, nishit.gu...@st.com wrote:
Is their any single fuction available in C++ that can determine that a
string
contains a numeric value.
The value cabn be in hex, int, float. i.e. "1256" , "123.566" ,
"0xffff" , It can also contain zero
you could try regexp's
http://freshmeat.net/projects/cpp_regex/
bool isValidNumber( string str ) {
if(str.length()<2) // do something or the next line crashes
if( str[1] == 'x' ) {
verify proper hex chars
some func to convert to hex
return true
}
else {
ostringstream oss( str )
double num;
num << oss;
if( num is valid )
return true
else
return false
Not really. For the string "123ZZZ" num is valid,
while "123ZZZ" is not a valid number.
The usual formulation in such cases is:
return oss >> num >> std::ws && oss.get() == EOF ;
If you don't want to allow whitespace, do
oss.unsetf( std::ios::skipws ) ;
before, and drop the "<< std::ws".
The problem here is that there is no one target type which will
accept all possible numbers. If you're willing to use two
streams, however, something like the following should work:
std::ostringstream si( str ) ;
si.unsetf( std::ios::basefield ) ;
std::ostringstream sd( str ) ;
int i ;
double d ;
return (si >> i >> std::ws && si.get() == EOF)
|| (sd >> d >> std::ws && sd.get() == EOF) ;
Personally, I'd go with something like:
static boost::regex const
number( "^[:space:]*[+-]?"
"(" "([1-9][0-9]*)"
"|" "(0[0-7]*)"
"|" "(0[xX][0-9a-fA-F]+)"
"|" "([0-9]+\.[0-9]*([Ee][+-]?[0-9]+)?)"
"|" "(\.[0-9]+([Ee][+-]?[0-9]+)?)"
"|" "([0-9]+[Ee][+-]?[0-9]+)"
")[:space:]*$" ) ;
return regex_match( str, number ) ;
Conversely, for the string "123" num may go eof
after reading and hence become invalid, while "123"
is a valid number.
The eofbit will be set after reading "123", but this doesn't
mean that the stream has failed. It only means that any further
attempt to read the stream will fail. (Note that std::ws is a
manipulator, which never "fails", i.e. it never sets failbit.)
}
} // end of isValidNumber
you could even return an int or enumeration to determine what type
with further tests
With boost::regex, you can capture the substrings which matched
parts of the regular expression in parentheses. Within the
or's, only one should not be empty, and which one tells you
which or matched.
My own regular expression class allows matching several regular
expressions in parallel, with the return code indicating which
one matched:
static Gabi::RegularExpression const
number =
Gabi::RegularExpression( "[+-]?[1-9][0-9]*", 10 ) ;
| Gabi::RegularExpression( "[+-]?0[0-7]*", 8 ) ;
| Gabi::RegularExpression( "[+-]?0[Xx][0-9a-fA-F]+", 16 )
| Gabi::RegularExpression( "[+-]?[0-9]+\.[0-9]*([Ee][+-]?
[0-9]+)?", 0 )
| Gabi::RegularExpression( "[+-]?\.[0-9]+([Ee][+-]?
[0-9]+)?", 0 )
| Gabi::RegularExpression( "[+-]?[0-9]+[Ee][+-]?[0-9]+",
0 ) ;
std::pair< int, std::string::const_iterator >
result
= number.match( str.begin(), str.end() ) ;
return result.second == str.end()
? result.first
: -1 ;
This would return -1 if no match, 0 for a floating point value,
and the base for an integer value. (I've since added features
to force an error if the match doesn't go to the end of the
string, so you could just use "return number.match(...).first;",
but this version isn't yet present at my site.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34