简体   繁体   中英

check what number a string ends with in C++

In a C++ MD2 file loader, I have a lot of frames, each with a name that ends with a number, such as

  • stand0
  • stand1
  • stand2
  • stand3
  • stand4
  • ...
  • stand10
  • stand11
  • run0
  • run1
  • run2

etc.

How do I get what the string is without the number behind? eg a function that changed "stand10" to just "stand"

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());

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.

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.
}

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]+$"), "");

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');
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM