using namespace std;
string digitch_ = "0123456789";
string integerch_ = digitch_ + "+-";
bool isInteger(const string & strg)
{
intu i;
// Check whether an entire string is a number or not
for (i = 0; i < strg.size(); ++i)
{
// The string is an integer with just pos or neg sign.
if ( integerch_.find(strg) != string::npos )
{
// Do nothing.
}
else
{
// Just one non-integer breaks and returns.
return false;
}
}
return true;
}
Any ideas?
--random
edit: added code tags -SiCrane
C++ Searching for chars from one string in another string...best approach
Hi all,
I'm using the STL to search for characters from one string in another string. I was just wondering is there is another way to do this more efficiently:
You can use the std::string::find_first_of() member function. ex:
std::string::size_type index = integerch_.find_first_of(digitch_);
std::string::size_type index = integerch_.find_first_of(digitch_);
Quote:Original post by SiCrane
You can use the std::string::find_first_of() member function. ex:
std::string::size_type index = integerch_.find_first_of(digitch_);
I've tried to use this, but I think that the logic is the reverse of what was used before. The previous version determines whether the entire string is an integer. However, the version
strg.find_first_of(integerch_)
looks for just one instance of intergerch_ within strg. This can be used as follows:
using namespace std;
bool isNotIntegerch(const string & strg)
{
if ( strg.find_first_of(integerch_) == string::npos )
{
// This means that there is no integerch_.
return true;
}
// This does not mean that all are integerch_! Only one needs to be.
return false;
}
To use find_first_of() I would have to define and search the entire universe of non-integer characters. This seems less efficient than the previous version.
Any suggestions for improvement? Possibly using streams?
--random
If you're specifically trying to determine whether your string is an integer, put it in a stringstream, read the integer off the stream, and check if the read was successful (!fail) and complete (eof).
Added bonus - you get the integer if there is one.
Added bonus - you get the integer if there is one.
Thanks Fruny,
I've thought about this, but I don't follow. As the argument being passed is a string regardless of character composition, how can I use a stringstream for truth? Won't the argument always be true? Or are you thinking that I pass the argument as a characters?
--random
I've thought about this, but I don't follow. As the argument being passed is a string regardless of character composition, how can I use a stringstream for truth? Won't the argument always be true? Or are you thinking that I pass the argument as a characters?
--random
std::string data = "12456";std::ostringstream oss(data);int number;oss >> number;if (oss.fail()){ // Couldn't read the number, so it can't be an int.}else if(!oss.eof()){ // Haven't reached the end of the string // so it's not just an int. }
Of course, that approach is designed to check for ints, and assumes that getting the actual number is a significant benefit. It wouldn't work for arbitrary set of characters - in which case, you're better off with find_first_not_of, or a regular expression engine. And if you don't need the number, but are doing massive string handling, you may have to roll a custom function.
Incidentally, that stringstream reading pattern is available in Boost as lexical_cast (which literally allows you to cast between strings and numbers). You might want to check it out.
Being the ASCII codepage lists the numerical characters consecutively, you can use this to determine whether a string is representing a numerical value.
bool isInteger( const string & strg ) const
{
for ( int n = strg.size()-1; n >= 0; --n )
{
if (strg[n] >= '0' && (strg[n] - '0') <= 9)
continue;
if (n == 0 && (strg[n] == '-' || strg[n] == '+')
continue;
return false;
}
return true;
}
bool isInteger( const string & strg ) const
{
for ( int n = strg.size()-1; n >= 0; --n )
{
if (strg[n] >= '0' && (strg[n] - '0') <= 9)
continue;
if (n == 0 && (strg[n] == '-' || strg[n] == '+')
continue;
return false;
}
return true;
}
Quote:Original post by Frunystd::string data = "12456";std::ostringstream oss(data);int number;oss >> number;if (oss.fail()){ // Couldn't read the number, so it can't be an int.}else if(!oss.eof()){ // Haven't reached the end of the string // so it's not just an int. }
Of course, that approach is designed to check for ints, and assumes that getting the actual number is a significant benefit. It wouldn't work for arbitrary set of characters - in which case, you're better off with find_first_not_of, or a regular expression engine. And if you don't need the number, but are doing massive string handling, you may have to roll a custom function.
Incidentally, that stringstream reading pattern is available in Boost as lexical_cast (which literally allows you to cast between strings and numbers). You might want to check it out.
Thanks Fruny,
So in my case, something like:
using namespace std;
bool isInteger(const string & strg)
{
ostringstream oss(strg);
int anInteger;
if (oss >> anInteger)
{
return true;
}
return false;
}
bool isReal(const string & strg)
{
ostringstream oss(strg);
float aFloat;
if (oss >> aFloat)
{
return true;
}
return false;
}
Do you think that this would be more efficient (use less cpu) than the original version?
--random
If you'd like to use a method similiar to your original (and extremely simple too), just use:
bool isInteger( const string &strg )
{
return (strg.find_first_not_of( integerch_ ) == string::npos);
}
bool isInteger( const string &strg )
{
return (strg.find_first_not_of( integerch_ ) == string::npos);
}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement