开发者

How to extract digit(s) from the end of string

Given strings like the following:

   sdfsd34 
    sdfdsf1

I would like to extract: 34, 1 using c++ (STL but no开发者_Go百科 boost), c.

thanks


You’re searching for the function string.find_last_not_of:

string str = "sdfsd34";
size_t last_index = str.find_last_not_of("0123456789");
string result = str.substr(last_index + 1);


A lot here depends on whether you're more comfortable with string manipulation, or with STL-style iterators and such. As @Konrad already pointed out, std::string has find_last_not_of built in, for anybody who likes string-style manipulation.

If you prefer, you can work with a string a bit more like a container, and find the first non-digit starting from the end:

std::string::iterator pos = std::find_if(
    mystring.rbegin(), 
    mystring.rend(), 
    std::not1(std::isdigit)).base();

In this case, the conversion from reverse_iterator to iterator happens to work out very nicely. The reverse_iterator returned by find_if will refer to the last element before a contiguous set of digits at the end of the string. The base of that, however, will refer to the first of the digits (or mystring.end() if there are no digits at the end or (unfortunately) if the whole string consists of digits).


Initial version, using <algorithm>:

string input("aasdf43");
string matches("01234567890");

string::iterator iter = find_first_of(input.begin(), input.end(), 
        matches.begin(), matches.end());

string next(iter, input.end());

stringstream intStream(next);
int intValue;
intStream >> intValue;

EDIT: Better to use member function:

string input("aasdf43");
string matches("0123456789");
size_t offset = input.find_first_of(matches);
string next(input.substr(offset));

stringstream intStream(next);
int intValue;
intStream >> intValue;

Just for good measure - an <algorithm> version not requiring check versus all digits.

string::reverse_iterator iter = find_if_not(input.rbegin(), input.rend(), 
    ([&](char c) { return c >= '0' && c <= '9';}));
reverse(input.rbegin(), iter);
string reversed(input.rbegin(), iter);

stringstream intStream(reversed);
int intValue;
intStream >> intValue;


Here is a C solution. You've to include stdio.h and ctype.h to get this to work.

char* str = "djafldjsalj124"; 
long n; 

char *s = str; 
while (*s && !isdigit(*s)) s++; 
if (*s)
{
 sscanf(s, "%d", &n);  
 printf("%d\n", n); 
}


If they're always at the end, then just start at the end of the string and look for a digit, when you get to the first non digit number, then you have it. Look at reverse_find, or find_reverse, or something like that. It's been a long time since I've done any string manipulation in STL. Being the old-timey c programmer that I am, I'd probably end up converting it to a char array (if it's not a super long string), and doing stupid pointer tricks, but thats just me.


The C++ solutions already posted are pretty reasonable. In C, you can use strpbrk. This gives the first occurance of any of a set of characters, so if it not guaranteed that the digits appear at the end of the string, you will need to call strpbrk until it returns null, saving the result of the previous call before the next call. There is no reverse strpbrk as there is for strchr, at least that I know of.


Assuming str is the string in question, and i will contain a pointer to the character where the number starts...

char* i;
for(i = str + strlen(str) - 1; i >= str && *i >= '0' && *i <= '9'; i--);
i++;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜