Reputation: 27
In a C++ MD2 file loader, I have a lot of frames, each with a name that ends with a number, such as
etc.
How do I get what the string is without the number behind? e.g. a function that changed "stand10" to just "stand"
Upvotes: 0
Views: 4056
Reputation: 20360
string::find_last_not_of("0123456789") and then string::substr()
that gives you the position of the last non digit/number. Just take all the preceding characters and that is the base name.
Increment by one to get the start of the number sequence at the end of the string.
Note: no error checking or other tests.
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string test = "hellothere4";
size_t last_char_pos = test.find_last_not_of("0123456789");
string base = test.substr(0, last_char_pos + 1);
EDIT
there is a problem with ALL the solutions when your "base name" has a number at the end.
for example, if the base string is "base1" then you can never get the proper base name. I assume you already are aware of this.
Or am I missing something? As long as the base name can't have a number at the end just before the postfix number it will work fine.
Upvotes: 5
Reputation: 506905
Just to show another way, reverse iterators:
string::reverse_iterator rit = str.rbegin();
while(isdigit(*rit)) ++rit;
std::string new_str(str.begin(), rit.base());
If you have boost::bind, you can make your life easier
std::string new_str(str.begin(),
std::find_if(str.rbegin(), str.rend(),
!boost::bind(::isdigit, _1)).base());
Upvotes: 4
Reputation: 29011
Just to complete it, one with find_first_of:
string new_string = str.substr(0, str.find_first_of("0123456789"));
just one line :)
Also, for these things, I like to use regular expressions (althought this case is very simple):
string new_string = boost::regex_replace(str, boost::regex("[0-9]+$"), "");
Upvotes: 1
Reputation: 90012
C-style way of doing it:
Iterate through your string character-by-character, starting from the left. When you read a number, stop, and mark it as the end of your string.
char *curChar = myString; // Temporary for quicker iteration.
while(*curChar != '\0') { // Loop through all characters in the string.
if(isdigit(*curChar)) { // Is the current character a digit?
*curChar = '\0'; // End the string.
break; // No need to loop any more.
}
++curChar; // Move onto the next character.
}
Upvotes: 1
Reputation: 995
Quick and dirty and not too elegant:
for (int i = str.GetLength()-1; i >= 0; i--)
{
if (!isdigit(str.GetAt(i)) break;
str.SetAt(i,'\0');
}
Upvotes: 0