2015-04-25 2 views
0

Предположим, что у меня есть разные функции, обращающиеся к одному String str (получение одного его символа), и я хочу, чтобы цикл через эту строку был с каждым доступом ... как я мог это достичь?C++: цикл по строке - итератор?

Например:

string str = "abc"; 
function1(); // returns "a" 
function2(); // returns "b" 
function3(); // returns "c" 
function4(); // returns "a" again 
function2(); // returns "b" again 
... 

Так в основном у меня есть различные функции с доступом к этой строке str и мне нужно какое-то итератор, который возвращается к первому символу str если конец str достигается.

+0

Итак, сделайте такой итератор. В чем проблема? – Lol4t0

ответ

3

Если вы действительно хотите использовать итератор вместо индексации, вы можете использовать cyclic_iterator, что-то вроде этого:

#ifndef CYCLIC_ITERATOR_H_INC_ 
#define CYCLIC_ITERATOR_H_INC_ 
#include <iterator> 

template <class FwdIt> 
class cyclic_iterator_t : public std::iterator<std::input_iterator_tag, typename FwdIt::value_type> { 
    FwdIt begin; 
    FwdIt end; 
    FwdIt current; 
public: 
    cyclic_iterator_t(FwdIt begin, FwdIt end) : begin(begin), end(end), current(begin) {} 

    cyclic_iterator_t operator++() { 
     if (++current == end) 
      current = begin; 
     return *this; 
    } 
    typename FwdIt::value_type operator *() const { return *current; } 
}; 

template <class Container> 
cyclic_iterator_t<typename Container::iterator> cyclic_iterator(Container &c) { 
    return cyclic_iterator_t<typename Container::iterator>(c.begin(), c.end()); 
} 

#endif 

Это весьма минимально итераторы go - например, в настоящее время он поддерживает только предварительный инкремент, а не пост-инкремент (и это передовой итератор, поэтому обо всем, что вы можете делать с итератором, является его увеличение и derefe его).

Тем не менее, для работы, которую вы себе представляете, это кажется адекватным.

+0

Спасибо, это похоже на работу :) – daniel451

2

Я бы просто проиндексировал из string с помощью модуля модуля %. Это даст вам пошаговое поведение, которое вы хотите.

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string str = "abc"; 
    for (int i = 0; i < 10; ++i) 
    { 
     std::cout << str[i % str.size()] << " "; 
    } 
} 

Output

a b c a b c a b c a 
+0

да ... но проблема в том, что нет ни одного цикла для цикла, но разные функции, выполняющие некоторые вещи и доступ к строке. Вы бы предложили «глобальный» индекс, чтобы каждая вызванная функция делала что-то вроде 'str [globalindex% str.size()]'? – daniel451

+0

Это действительно зависит от структуры вашей программы. Я не уверен, как связаны «function1», «function2» и т. Д. Являются ли они классными методами? Можете ли вы объяснить, какова ваша общая цель? – CoryKramer

+0

Это часть консольного инструмента криптоанализа ... функции не связаны (ни в классе, ни в семантическом ключе). – daniel451

0

Я не знаю, сколько раз вам нужно, чтобы это работало, но здесь вы (Вы можете изменить его в соответствии с вашими потребностями):

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string str = "abc"; 

    bool bAgain = true; 

    int Max = str.length() + 1; 

    for(int i = 0; i < Max; i++) 
    { 
     std::cout << str[i] << "\n"; 

     if(bAgain) 
     { 
      if(i == Max - 1) 
      { 
       i = -1; 
       bAgain = false; 
       continue; 
      } 
     } 
    } 
} 

`

Output

a 
b 
c 
a 
b 
c 
Смежные вопросы