2016-05-28 3 views
1

я пытался реализации метода C++, которая удаляет начальные и конечные пробелыЧто происходит с итераторами, если вы удаляете() элемент в C++?

string::iterator begin = s.begin(); 
    string::iterator end = s.end()-1; 
    while (*begin == ' ') { 
     cout << "*begin is: " << *begin << endl; 
     begin++; 
    } 
    while (*end == ' ') { 
     cout << "*end is: " << *end << endl; 
     end--; 
    } 
    s.erase(s.begin(),begin); 
    s.erase(end+1,s.end()); 

Тогда мой код Разбился. После нескольких отладок я обнаружил, что на самом деле это вызвало мое «неправильное расположение итератора» (я сделал это имя ... не знаю, что именно эта ошибка называется ...), когда я erase() элементов из строки. Так что, если я делаю это вместо того, чтобы (изменить процедуру):

string::iterator begin = s.begin(); 
    while (*begin == ' ') { 
     cout << "*begin is: " << *begin << endl; 
     begin++; 
    } 
    s.erase(s.begin(),begin); 


    string::iterator end = s.end()-1; 
    while (*end == ' ') { 
     cout << "*end is: " << *end << endl; 
     end--; 
    } 
    s.erase(end+1,s.end()); 

нет больше проблем: D

Так что я действительно хотел бы знать, что именно происходит с итератора, когда вы erase() элемент из него. Например, если вы erase() первые/последние два элемента, что произойдет с s.end()/s.begin()?

+1

Я считаю, что термин, который вы ищете, является недействительным итератором. – DeiDei

+0

Когда вы удаляете все существующие итераторы, они недействительны, точно так же, как в описании стирания. Поэтому, чтобы вы могли стереть с начала и конца, вам нужно разделить его на два прохода, где вы сначала удаляете начальные пробелы, а затем получаете новые итераторы для стирания конечных. –

+0

Instrad с использованием ручных циклов, посмотрите на ['find_first_not_of()'] (http://en.cppreference.com/w/cpp/string/basic_string/find_first_not_of) и ['find_last_not_of()'] (http://en.cppreference.com/w/cpp/string/basic_string/find_last_not_of). –

ответ

5

требования по std::string сказать: (§ [string.require]/4):

Список литературы, указатели и итераторы со ссылкой на элементы последовательности basic_string может быть признана недействительной в следующих применений, что basic_string object:
[...]
- Вызов функций неконстантного члена, кроме оператора [], спереди, сзади, начала, rbegin, end и rend.

Я бы просто использовать substr, что-то вроде этого:

s = s.substr(begin, end-begin); 

я бы, вероятно, также использовать функции-члены струны, чтобы сделать поиск:

auto begin = s.find_first_not_of(' '); 
auto end = s.find_last_not_of(' '); 
s = s.substr(begin, end-begin); 

Поскольку это делает работу в одной операции он избегает любых проблем с недействительностью итератора (и в качестве бонуса он может быть немного быстрее).

+0

Стандарт можно найти здесь [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf). –

+0

Спасибо, Джерри, это действительно удобное и чистое решение. –

Смежные вопросы