2016-12-07 2 views
0

То, что я пытаюсь сделать, это заставить пользователя ввести номер телефона в предпочтительном формате, а затем удалить вспомогательные символы, которые пользователь использовал во входных данных, используя цикл, который сравнивает каждый символ в строке с другим набором определенных вспомогательных символов, если есть совпадение, он стирает этот символ из строки. Я делаю это как практическую проблему, чтобы развить мое недоумение итераторов. Я успешно сделал это с тривиальным циклом. Однако, когда я пытаюсь сделать это таким образом к моему удивлению, когда есть два вспомогательных символа, таких как «(+», цикл не запускается для следующего символа, который в этом случае является «+». Он перенаправляет «9» »и работает отлично после этого.Он делает то же поведение, если другие вспомогательные символы присутствуют позже в строке.Я проверил это, поставив cout < < * i прямо под первым циклом. Я не понимаю, почему это будет происходить? из-за этого программа не в состоянии сделать то, что он должен и из пут «+91892333» вместо желаемого «91892333».Неисправность итератора при прохождении через строку

#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 

string main = "(+91)892-333"; 
string dictionary = "(+)-"; 

for(string::iterator i = main.begin(); i != main.end(); i++) 
{ 


    for(char word : dictionary) 
    { 

       if(*i == word) 
       { 
        main.erase(i); 
        break; 
       } 
    } 
} 

cout << main; 

} 

ответ

0

Согласно documentationerase аннулирует итераторы. Таким образом, после того, как вы звоните erase вы не должны использовать iterato rs, полученным ранее, или вы получаете UB. В вашем случае erase не меняет итератор, но перемещает конец, если строка после стирания символа оставлена ​​на один символ. Таким образом, ваш итератор теперь указывает на следующий символ. Но это поведение не гарантируется, std :: string может выделять новый буфер и перемещать туда данные, оставляя старые итераторы, указывающие на никуда.

+0

получил добавление i-- после того, как функция стирания работает как шарм, но не должен ли итератор быть недействительным? –

+0

Когда вы пишете на C++, очень часто используется boost. Это своего рода игровая площадка для STL. Существует boost/algorithm/string/erase.hpp, где вы можете найти функции, которые делают именно то, что вы хотите. Или вы можете использовать std :: remove_if, а затем удалить неиспользуемый конец строки с помощью substr. –

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