Reputation: 11002
Let us assume I have different functions accessing a single String str
(getting a single character of it) and I want to loop through this string with every access...how could I achieve this?
For example:
string str = "abc";
function1(); // returns "a"
function2(); // returns "b"
function3(); // returns "c"
function4(); // returns "a" again
function2(); // returns "b" again
...
So basically I have different functions accessing this string str
and I need some kind of iterator which gets back to the first character of str
if the end of str
is reached.
Upvotes: 0
Views: 185
Reputation: 116
I don't know how many times you need this to work, but here you are(You can edit it to fit with your needs):
#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;
}
}
}
}
`
a
b
c
a
b
c
Upvotes: 0
Reputation: 490108
If you really want to use an iterator instead of indexing, you could use a cyclic_iterator, something like this:
#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
This is quite minimal as iterators go--for example, it currently only supports pre-increment, not post-increment (and it's a forward iterator, so about all you can do with the iterator is increment it and dereference it).
Nonetheless, for the job you envision, it seems to be adequate.
Upvotes: 3
Reputation: 117856
I would just index out of the string
using the %
modulus operator. This will get you the wraparound behavior you want.
#include <iostream>
#include <string>
int main()
{
std::string str = "abc";
for (int i = 0; i < 10; ++i)
{
std::cout << str[i % str.size()] << " ";
}
}
a b c a b c a b c a
Upvotes: 2