-2

I am looking to make a C++ function that has the following prototype:

char *trim(char *string)

What I want this function to do is the following:

  • Trim all the non, alphabetic, numeric characters
  • If there is a space encountered, it is to trim the space and the appending characters
  • Return the trimmed character array

Example:

Input: *&^!@^ThisIsA#Test String;'{><,.

Output: ThisIsATest

ZioN
  • 550
  • 2
  • 11
  • 35

2 Answers2

3

One option is std::copy_if to copy the good characters to a return buffer:

char *trim(const char *str) {
    std::size_t len = strlen(str);

    char *ret = new char[len + 1]{}; //allocate space and initialize
    std::copy_if(
        str, //from beginning
        std::find(str, str + len, ' '), //to first space (or end)
        ret, //copy to beginning of buffer
        isalnum //the alphanumeric characters
    );

    return ret; //return the buffer
}

int main() {
    std::cout << trim("ab$#h%#.s354,.23nj%f abcsf"); //abhs35423njf
    std::cout << trim("adua9d8f9hs.f,lere.r"); //adua9d8f9hsflerer
}

Notice how my example completely ignores the fact that you have to deallocate the memory you allocated in trim, which is ok in this case because the program ends right after. I strongly suggest you change it to use std::string instead. It both eases the definition of trim because of the std::begin and std::end compatibility, and manages the memory for you.

chris
  • 60,560
  • 13
  • 143
  • 205
  • You need to cast to select the right overload of `isalnum()`. I agree with `string` it’s nicer: `copy_if(s.begin(), find(s.begin(), s.end(), ' '), back_inserter(result), static_cast(isalnum));` or more generally `find_if()` with `isspace()`. – Jon Purdy Nov 16 '12 at 08:57
  • @JonPurdy, Are you sure you need to cast it? GCC gave me nothing. Anyway, I did think about `isspace`, and I agree it's a suitable replacement. I was kind of just going with the wording of the question, but it's a good mention. – chris Nov 16 '12 at 09:03
  • I had to cast on Ideone. I included the header as ``, though; if you used `` then the behaviour might differ. – Jon Purdy Nov 16 '12 at 09:06
  • @JonPurdy, I used `` as well. It's 4.7.2, for reference. All VS11 gives me is the usual warning for it possibly not being safe (though it should be in this case), and it looks like http://llvm.org/demo doesn't have `copy_if`. – chris Nov 16 '12 at 09:11
  • @chris current errors I am getting "C2143: syntax error : missing ';' before '{'" for this line `char *ret = new char[len + 1]{};` and "C2039: 'copy_if' : is not a member of 'std'". I am testing in VS, but will deploy it on a IMB mid rage machine – ZioN Nov 16 '12 at 09:28
  • @ZioN, You need to include `` if you haven't, and `std::copy_if` is C++11. What else is C++11 is the initializer for the array. You can just stick a 0 in there for that one. – chris Nov 16 '12 at 11:19
  • @ZioN, There's also a pretty good implementation of it [here](http://lists.boost.org/Archives/boost/2001/01/8022.php). – chris Nov 16 '12 at 14:37
0

Not sure if this is the best way, performance wise, but it is the most logical way to me. copy_if seem to not exist. But looking at ASCII table www.asciitable.com I loop through the character array and only copy the alphabetic numeric character to my string object, and until I find a space or reach the array's end.

char *trim(char *str)
{
    std::size_t len = strlen(str);

    string temp = "";

    for (size_t k = 0; k < len; k++)
    {
            // If space found end the process
            if(str[k] == 32)
            {
                break;
            }
            else if ((str[k] >= 48) && (str[k] >= 57)) // numbers
            {
                temp += str[k];
            }
            else if ((str[k] >= 65) && (str[k] >= 90)) // uppercase letters
            {
                temp += str[k];
            }
            else if ((str[k] >= 97) && (str[k] >= 122)) // lowercase letters
            {
                temp += str[k];
            }
    }

    // Convert String to char*
    char * writable = new char[temp.size() + 1];
    std::copy(temp.begin(), temp.end(), writable);
    writable[temp.size()] = '\0';

    return writable;
}          

Got the idea to convert string to char* from here convert-stdstring-to-const-char-or-char

Community
  • 1
  • 1
ZioN
  • 550
  • 2
  • 11
  • 35