0

I am trying to use C++ vector instead of C arrays, but I have some problems. This is my code:

size_t i;
//Filter save files
for (i = 0; i != files.size(); i++){
    cout << files.at(i).find(FILE_HEAD) << ' ' << files.at(i) << endl;
    if ((files.at(i).find(FILE_HEAD) != 0)){
        files.erase(files.begin() + i);
    }
}
cout << "Found files:\n";
for (i = 0; i != files.size(); i++){
    cout << i << " - " << files.at(i) << endl;
}

files is a std::vector<std::string> and I want to remove all elements which not contain FILE_HEAD. But this doesn't work properly, in my test file.size() is 14 but it goes in for only 7 times. Can anyone help me? Thank you!

Vitto
  • 361
  • 3
  • 17
  • 1
    Use `std::remove_if`. – chris Jul 10 '14 at 14:18
  • 1
    Once you've removed an element, you've decreased the effective size of your vector. This will cause issues with a fixed for loop. For a quick workaround, iterate backwards. Better yet, follow the other suggestions. – Ben Jul 10 '14 at 14:21

2 Answers2

2

You could use:

files.erase(std::remove_if(files.begin(),files.end(),
            [](const std::string& str){return str.find(FILE_HEAD) == std::string::npos;}),
            file.end());
TNA
  • 2,595
  • 1
  • 14
  • 19
0

The problem is following: when you erase i-th element, you still increase i, so you skip one element. Try to add i--; right after files.erase(files.begin() + i); to fix it (only for testing!). But please do not invent such bicycles! It is better to use std::remove_if instaed of such problematic implementations.

Ilya
  • 4,583
  • 4
  • 26
  • 51
  • AFAIK after removing element from vector the iterator is no longer valid. if it is windows code the erase return a valid iterator to allow the loop continue. – SHR Jul 10 '14 at 14:23
  • @SHR, but in line `files.at(i).find(FILE_HEAD)` we have getting an access to i-th element, so we skip one element after each `erase()`. – Ilya Jul 10 '14 at 14:26