итератор строки c ++ - PullRequest
       5

итератор строки c ++

8 голосов
/ 24 марта 2011

Я пытаюсь сделать оператор if внутри цикла с итератором над строкой, но не могу понять, как получить текущий символ для оператора if:

for (std::string::iterator i=buffer.end()-1; i>=buffer.begin(); --i) {
    if (!isalpha(*i) && !isdigit(*i)) {
        if(i != "-") { // obviously this is wrong
            buffer.erase(i);
        }
    }
}

Может кто-топомогите мне получить текущий символ, чтобы я мог сделать несколько дополнительных операторов if?

Ответы [ 5 ]

19 голосов
/ 24 марта 2011

Я не могу понять, как получить текущий символ

Вы делаете это дважды здесь:

if (!isalpha(*i) && !isdigit(*i))

При разыменовании итератора (*i) вы получаете элемент, на который он указывает.

"-"

Это строковый литерал, а не символ. Символьные константы используют одинарные кавычки, например, '-'.

for (std::string::iterator i=buffer.end()-1; i>=buffer.begin(); --i)

Это было бы намного проще с обратными итераторами:

for (std::string::reverse_iterator i = buffer.rbegin(); i != buffer.rend(); ++i)
3 голосов
/ 24 марта 2011
if(i != "-")

должно быть

if(*i != '-')
2 голосов
/ 24 марта 2011

Другие ответы решили конкретную проблему, которая у вас есть, но вы должны знать, что существуют разные подходы для решения вашей актуальной проблемы: стереть элементы, которые заполняют условие .Это может быть легко решено с помощью удаления / стирания идиомы:

// C++0x enabled compiler
str.erase( 
    std::remove_if( str.begin(), str.end(), 
                  [](char ch) { return !isalpha(ch) && !isdigit(ch) && ch != '-' } ),
    str.end() );

Хотя это может показаться громоздким на первый взгляд, если вы уже видели его пару раз, это уже не удивительно, и это эффективный способ удаления элементов из вектора или строки.

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

// at namespace level, sadly c++03 does not allow you to use local classes in templates
struct mycondition {
   bool operator()( char ch ) const {
      return !isalpha(ch) && !isdigit(ch) && ch != '-';
   }
};
// call:
str.erase( 
    std::remove_if( str.begin(), str.end(), mycondition() ),
    str.end() );
2 голосов
/ 24 марта 2011

Чтобы получить персонажа, просто скажите *i, но этого недостаточно.Ваш цикл недопустим, потому что он не может уменьшаться до begin.Вы должны использовать обратные итераторы или алгоритм remove_if.

1 голос
/ 24 марта 2011

Выше это прямо в предыдущем выражении if: i является итератором, поэтому *i дает символ, на который ссылается итератор.

Обратите внимание, что если вы собираетесь перебирать коллекцию в обратном направлении, обычно проще использовать reverse_iterator с rbegin и rend. Возможно, я бы вместо этого использовал предварительно упакованный алгоритм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...