Thread: remove element from vector<string>

  1. #1
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69

    remove element from vector<string>

    hi,

    im trying to remove all elements starting with the a...im not sure why this doesnt work?

    Code:
    /* remove element if it begins with a */
    	for (vector<string>::iterator k = final.begin(); k!=final.end(); ++k) {
    		if(*k.find("a")==0)
    			final.erase(*k);
    	}
    thanks..

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The call to erase invalidates the iterator k. You must use the return value from erase to get the next available iterator. You should also pass the iterator to erase, not the string.
    Code:
    	for (vector<string>::iterator k = final.begin(); k!=final.end(); ) {
    		if(*k.find("a")==0)
    			k = final.erase(k);
    		else
    			++k;
    	}

  3. #3
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69
    hmmm..still doesnt compile....error msg below

    test.cpp: In function `std::vector<std::string, std::allocator<std::string> >
    readFruit()':
    test.cpp:50: error: `find' undeclared (first use this function)
    test.cpp:50: error: (Each undeclared identifier is reported only once for each
    function it appears in.)
    test.cpp:51: error: no matching function for call to `std::vector<std::string,
    std::allocator<std::string> >::erase(std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >&)'

  4. #4
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    noob error
    Code:
    *k.find("a")
    k->find("a")
    http://www.cppreference.com/operator_precedence.html

    to remove the string from the vector do
    Code:
    for(vector<string>::iterator k = ... ; ... ; ...) //bla bla bla
        if(k->find("whatever") == 0)
            thy_vector.erase(k);
    yes, it receives the pointer, not the dereferenced string
    Last edited by xErath; 06-30-2005 at 06:47 PM.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Instead of using find, you should just check to see if the string is not empty and the first character is 'a' (e.g. if (!k->empty() && k[0] == 'a')).

  6. #6
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69
    Thank you xErath...yes im a nubie!

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    ups.. me errors sometime
    Code:
    for(vector<string>::iterator k = ... ; ... ; ...) //bla bla bla
        if(k->find("whatever") == 0)
            thy_vector.erase(k--);
    k-- to revisit the new string in the next cicle, which is pushed backwards by erase

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What if k is equal to begin()? The method I posted above is probably better for this case.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Use the remove_if function in <algorithm> along with the vector's erase member function:

    Code:
    bool StartsWitha(const std::string& str)
    {
        // Return true for any string beginning with lower-case 'a'
        return str.length() && str[0] == 'a';
    }
    
    ...
    
    // Erase all strings beginning with 'a' from the vector
    final.erase( std::remove_if( final.begin(), final.end(), StartsWitha ), final.end() );
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's faster if you make that a functor instead of a function.
    Code:
    struct starts_with_a {
      bool operator ()(const std::string &str) {
        return !str.empty() && str[0] == 'a';
      }
    };
    
    final.erase( std::remove_if( final.begin(), final.end(), starts_with_a() ), final.end() );
    This way, the compiler can inline the call.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 01-05-2008, 11:30 PM
  2. Modify an single passed array element
    By swgh in forum C Programming
    Replies: 3
    Last Post: 08-04-2007, 08:58 AM
  3. Sorting a 2-dimensional array
    By kmoyle73 in forum C++ Programming
    Replies: 3
    Last Post: 05-05-2004, 01:54 PM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. sorting
    By penny_731729 in forum C Programming
    Replies: 3
    Last Post: 04-28-2003, 10:56 AM