Is this code to find an int in a string okay ?

D

Diwa

Hi Guys,

Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")

// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");

std::string str;

for (int i=0; i<strs.size(); i++)
{
str = "";

int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}

// --------------------------------------------------------------

Thanks
-- Diwa
 
J

Jim Langston

Diwa said:
Hi Guys,

Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")

// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");

std::string str;

for (int i=0; i<strs.size(); i++)
{
str = "";

int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}


This code looks okay. Although I wonder what you would want with a string
such as
"KFStat30A02". Your code could be described as finding the first continuous
number in a string. I really don't think you can simply if too much though
from what you already have, other than making it a function returning a
std::string.
 
V

Victor Bazarov

Jim said:
Diwa said:
Hi Guys,

Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")

// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");

std::string str;

for (int i=0; i<strs.size(); i++)
{
str = "";

int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}


This code looks okay. Although I wonder what you would want with a
string such as
"KFStat30A02". Your code could be described as finding the first
continuous number in a string. I really don't think you can simply
if too much though from what you already have, other than making it a
function returning a std::string.


I would probably add the ability to extract the substring as a number
in a given base. E.g., "KFStat30A02" in base 10 would yield "30" and
in base 16 would yield "F"... :) Or make it smarter and able to
recognize the 'x' or 'X' after the leading 0...

V
 
D

Daniel T.

Diwa said:
Hi Guys,

Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")

// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");

std::string str;

for (int i=0; i<strs.size(); i++)
{
str = "";

int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}

// --------------------------------------------------------------

Thanks


What you have is fine, just wrap it into a function and it will look
like this:

string get_int( const string& s )
{
string result;
string::size_type front = s.find_first_of( "0123456789" );
if ( front != string::npos )
{
string::size_type back =
s.find_first_not_of( "0123456789", front );
result.assign( s, front, back - front );
}
return result;
}

.... or you can get creative:

bool is_digit( char c )
{
return isdigit( c );
}

string get_int( const string& s )
{
string::const_iterator front = find_if( s.begin(), s.end(),
&is_digit );
string::const_iterator back = find_if( front, s.end(),
compose1( logical_not<bool>(), ptr_fun( &is_digit ) ) );
return string( front, back );
}

(note: compose1 is part of STL, not part of the standard.)

Once you have the above function, you can operate on your array with
transform.

int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");

vector<string> ints;

transform( strs.begin(), strs.end(),
back_inserter( ints ), &get_int );

for ( int i = 0; i < strs.size(); ++i )
cout << strs << ' ' << ints << '\n';
}
 
J

James Kanze

Is there any better way than below to find an int in a string
(e.g. "30" in "KFStat30A")

boost::regex.

If for some reason, you can't use Boost (most people probably
can't), then beg, borrow or steal some other regular expression
class. You don't want to do anything with text without one.
 
D

Diwa

Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")
// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");
std::string str;
for (int i=0; i<strs.size(); i++)
{
str = "";
int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}


This code looks okay. Although I wonder what you would want with a string
such as "KFStat30A02".
- Show quoted text -


The strings come from a database. The "30" in that string represents
the 30 yr treasury bond. Only the first two strings (KFStat30A and
KFStat2A) were valid ones. I had put the other three strings just for
testing purpose.
 
D

Diwa

Diwa said:
Is there any better way than below to find an int in a string (e.g.
"30" in "KFStat30A")
// --------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
vector<string> strs ;
strs.push_back("KFStat30A");
strs.push_back("KFStat2A");
strs.push_back("555555");
strs.push_back("KKKKKK");
strs.push_back("KKKK555");
std::string str;
for (int i=0; i<strs.size(); i++)
{
str = "";
int beg = strs.find_first_of("0123456789");

if (beg != string::npos)
{
int end = strs.find_first_not_of("0123456789", beg);
str.assign(strs, beg, end-beg);
}

cout << strs << " " << str << "\n";
}
return 0;
}

// --------------------------------------------------------------

What you have is fine, just wrap it into a function and it will look
like this:

string get_int( const string& s )
{
string result;
string::size_type front = s.find_first_of( "0123456789" );
if ( front != string::npos )
{
string::size_type back =
s.find_first_not_of( "0123456789", front );
result.assign( s, front, back - front );
}
return result;

}

... or you can get creative:

bool is_digit( char c )
{
return isdigit( c );

}

string get_int( const string& s )
{
string::const_iterator front = find_if( s.begin(), s.end(),
&is_digit );
string::const_iterator back = find_if( front, s.end(),
compose1( logical_not<bool>(), ptr_fun( &is_digit ) ) );
return string( front, back );

}


What would the above func return if the string (e.g. KFStat30A55BB)
contains 2 ints instead of one ?
 
D

Diwa

boost::regex.

If for some reason, you can't use Boost (most people probably
can't), then beg, borrow or steal some other regular expression
class. You don't want to do anything with text without one.

Thanks. That was what I originally wanted to use since we are using
boost anyway in our code. But later we decided against it since we do
not require any regex parsing except for this one. Boost regex would
have been an overkill especially considering the fact that boost regex
requires its library to be linked to the app. (If I am not wrong)
 
D

Daniel T.

Diwa said:
Daniel T. wrote:

What would the above func return if the string (e.g. KFStat30A55BB)
contains 2 ints instead of one ?

The first int. Both "get_int" functions above work in the same way. They
scan the string looking for the first digit, then scan from there
looking for the first non-digit, then output a string containing all the
data between the two positions found.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top