user3856804
user3856804

Reputation: 65

Iterator woes with C++ strings

For an assignment, we have to do a large program that manipulates C++ strings in a variety of ways. Most of it is working, but this particular function is messing with me. I am trying to cycle through a string and remove all non-alphanumeric (tab, blank newline) characters before the first alphanumeric one occurs, and then end the string when the first non-alphanumeric character appears again. For example, " bob jon" would be saved as "bob". Something is going wrong where every string is considered empty. Most peers have been telling be that

*(point++) = *marker;

can't be done and that I should change this before trying anything else...is this a way to increment the iterator while assigning its value to another iterator's value? Is it that the problem or something else?

void clean_entry( const string& j, string& k )
{
    string::iterator point = k.begin();
    bool checker = false;
    //cycle through the constant string and check for numbers and letters
    for(string::const_iterator marker = j.cbegin(); marker!=j.cend(); ++marker)
    {
        if( isalnum(*marker) == true )
        {
           *(point++) = *marker; //copy to the new k string if alphanum, and increment iterator
            cout << "I found a real letter!" << endl; //debugging
            checker = true;
        }
        else if( checker == true )
            break;
    }
    cout << "So far we have " << k << endl; //debugging
    if (checker == false )
        k = "(empty word)";

    cout << "The new string is " << k << " apparently." << endl; //debugging
}

Upvotes: 2

Views: 81

Answers (1)

T.C.
T.C.

Reputation: 137315

  1. isalnum doesn't return bool. It returns int. The guarantee is that it returns nonzero if the character is alphanumeric and zero otherwise.This means that you can't compare the return value to true, as that comparison causes true to be converted to int, yielding 1, before the comparison is done.. if(isalnum(*marker)) is both idiomatic and actually works.

    Similarly, if( checker == true ) is bloated and should be if(checker), and if (checker == false ) should be if(!checker).

  2. Your interface is questionable, since the caller must ensure that k's size is large enough to accommodate the resulting string. Better to clear k and then use push_back() or similar rather than an iterator.

On the assumption that k.size() is sufficiently large, there's nothing wrong with *(point++) = *marker;.

Upvotes: 3

Related Questions