Jump to content
  • Advertisement
Sign in to follow this  
random_thinker

C++ Searching for chars from one string in another string...best approach

This topic is 4845 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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:
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

Share this post


Link to post
Share on other sites
Advertisement
You can use the std::string::find_first_of() member function. ex:

std::string::size_type index = integerch_.find_first_of(digitch_);

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
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.



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

Share this post


Link to post
Share on other sites
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);
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!