2014-07-10 1 views
0

C 배열 대신 C++ 벡터를 사용하려고하지만 몇 가지 문제가 있습니다. 이건 내 코드입니다 :std :: vector의 요소 제거 <std::string>

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; 
} 

filesstd::vector<std::string> 내가 FILE_HEAD를 포함하는 모든 요소를 ​​제거합니다. 그러나 이것은 제대로 작동하지 않습니다. 내 테스트에서 file.size()은 14이지만 7 회만 있습니다. 누구든지 나를 도울 수 있습니까? 고맙습니다!

+1

사용'표준 : remove_if'합니다. – chris

+1

요소를 제거하면 벡터의 유효 크기가 감소합니다. 이렇게하면 고정 for 루프에 문제가 발생할 수 있습니다. 빠른 대안을 얻으려면 거꾸로 반복하십시오. 더 나은 아직, 다른 제안을 따르십시오. – Ben

답변

1

당신은 사용할 수 있습니다

files.erase(std::remove_if(files.begin(),files.end(), 
      [](const std::string& str){return str.find(FILE_HEAD) == std::string::npos;}), 
      file.end()); 
+0

감사합니다. remove_if를 몰랐습니다. – Vitto

+2

C++ 11 경고. 일부 오래된 컴파일러에서는 지원되지 않습니다. – SHR

+0

이것은 훌륭한 대답입니다. 나는 람다 함수의 사용을 좋아한다. – tn3rt

0

문제는 다음과 같습니다. i 번째 요소를 지울 때 여전히 i이 증가하므로 하나의 요소를 건너 뜁니다. 을 files.erase(files.begin() + i); 바로 뒤에 추가하여 수정하십시오 (테스트 용!). 그러나 그런 자전거는 발명하지 마십시오! 이러한 문제가있는 구현을 std :: remove_if instaed 사용하는 것이 좋습니다.

+0

AFAIK 벡터에서 요소를 제거한 후에 반복기가 더 이상 유효하지 않습니다. 그것이 윈도우 코드라면 지우기는 루프를 계속할 수 있도록 유효한 반복자를 반환합니다. – SHR

+0

@SHR,하지만'files.at (i) .find (FILE_HEAD)'줄에는 i 번째 요소에 대한 액세스 권한이 있으므로 각 erase() 후에 한 요소를 건너 뜁니다. – Ilya