C ++ removes punctuation line by line, erases () / iterator

I know that I am not the first person to raise the problem using reverse iterators trying to call the erase () method on strings. However, I could not find any good ways.

I am reading the contents of a file containing a bunch of words. When I read the word, I want to pass it to a function that I called stripPunct. However, I ONLY want to pull off the punctuation at the beginning and end of the line, and not in the middle.

So for example:

(word) follows strip '(' and ')', which leads to a simple word

no! must strip '!' as a result just don't

So my logic (which I am sure could be improved) was to have two while loops, one starting at the end and one at the beginning, crossing and erasing until it reaches the punctuation char.

void stripPunct(string & str) {
    string::iterator itr1 = str.begin();
    string::reverse_iterator itr2 = str.rbegin();

    while ( ispunct(*itr1) ) {
        str.erase(itr1);
        itr1++;
    }

    while ( ispunct(*itr2) ) {
        str.erase(itr2);
        itr2--;
    }
}

However, it obviously does not work, because erase () requires a regular iterator, not reverse_iterator. But in any case, I feel that this logic is pretty inefficient.

In addition, I tried to use only the regular iterator instead of reverse_iterator, starting it on str.end () and then decreasing it, but it says that I cannot dereference the iterator if I start it on str.end ().

Can someone help me with a good way to do this? Or maybe point to a workaround for what I already have?

Thank you so much in advance!

------------------ [EDIT] -------------------------- -

, :

// Call the stripPunct method:

stripPunct(str);
if ( !str.empty() ) { // make sure string is still valid
  // perform other code
}

stripPunct:

void stripPunct(string & str) {
   string::iterator itr1 = str.begin();
   string::iterator itr2 = str.end();

   while ( !(str.empty()) && ispunct(*itr1) ) 
       itr1 = str.erase(itr1);

   itr2--;
   if ( itr2 != str.begin() ) {

       while ( !(str.empty()) && ispunct(*itr2) ) {
           itr2 = str.erase(itr2);
           itr2--;
       }
   }
}
+3
3

-, :

  • erase() itr1, itr2.
  • reverse_iterator , ++, -- ( , ).

, , , charater, . find_if() :

int not_punct(char c) {
    return !ispunct((unsigned char) c);
}

void stripPunct(string & str) {
    string::iterator itr = find_if( str.begin(), str.end(), not_punct);

    str.erase( str.begin(), itr);

    string::reverse_iterator ritr = find_if( str.rbegin(), str.rend(), not_punct);

    str.erase( ritr.base(), str.end());
}

, base() "" , reverse_iterator. , base() ( ) - , .

, http://drdobbs.com/cpp/184401406, reverse_iterator::base() . " 3: , _". , , " STL" .

+4

iterator:: end(), ( ), .

: , , .

0

If you are not opposed to negative logic, you can do the following:

string tmp_str="";
tmp_str.reserve(str.length());
for (string::iterator itr1 = str.begin(); itr1 != str.end(); itr1++)
{
   if (!ispunct(*itr1))
   {
      tmp_str.push_back(*itr1);
   }
}
str = tmp_str;
0
source

All Articles