Reverse an array without affecting special characters

I found this little programming challenge here. The task is to take a string and reverse only the alphabetic characters in it, leaving any other characters unaffected.
So, given the string:

a,b$c

The program should output:

c,b$a

I think that the best method is to walk a pair of pointers inwards from both ends of the string at the same time, examining the characters they point to. If the character being examined at either end is not a letter, keep going inwards. Once both characters are letters, swap them. Finish when the pointers meet in the middle.

Here is my implementation in C:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

void swap(char *a, char *b)
{
    char temp = *a;
    *a = *b;
    *b = temp;
}

void reverse(char *str)
{
    char *p1 = str;
    char *p2 = str + strlen(str) - 1;
    while (p1 < p2) {
        while (!isalpha(*p1)) p1++;
        while (!isalpha(*p2)) p2--;
        if (p1 < p2) {
            swap(p1, p2);
            p1++;
            p2--;
        }
    }
}

int main(void)
{
    char str[6];
    strcpy(str, "a,b$c");
    reverse2(str);
    printf("%s\n", str);
    return 0;
}

While I was writing this it occurred to me that it would be nice if you could have a filtered view into the string that hid the special characters, and then you could just reverse what you can see. Then I remembered boost::filter_iterator, and found that it can do just that, so here’s my C++ version using filter_iterator from Boost:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <boost/iterator/filter_iterator.hpp>

struct is_alpha
{
    bool operator()(char c)
    {
        return std::isalpha(c);
    }
};

void reverse(char *str)
{
    const size_t len = std::strlen(str);
    typedef boost::filter_iterator<is_alpha, char*> FilterIter;
    is_alpha predicate;
    FilterIter first(predicate, str, str + len);
    FilterIter last(predicate, str + len, str + len);
    std::reverse(first, last);
}

int main()
{
    char str[6];
    strcpy(str, "a,b$c");
    reverse(str);
    std::cout << str << "\n";
}

Reference: Filter Iterator