Pintun
Pintun

Reputation: 736

Using array of boost range_iterator to split a string

i would like to process an undefinitely long string in C++ by chunks of a given fixed length (e.g. 15 chars).

The string is an attribute of the class in charge of processing it (let's call the class "Person" and the attribute "_description"), and external code must call a method to process each chunk sequentially, e.g. Person::processDescription(). Another method allows to see if there is one more chunk to process, e.g. Person::isThereMoreDescriptionToBeProcessed().

In order to avoid dealing with indexes and possible side effects (errors with +1/-1, init..), someone suggested me to store an array of range_iterators (boost) and iterate over them for processing, but I don't know the range_iterator concept and Boost docs did not help too much here.

I guess I will store 2 items (e.g. _currentItem and _endItem) as attributes of Person and do a check like

_currentItem == _endItem

in isThereMoreDescriptionToBeProcessed() and I guess I will do something like

_currentItem++

at the end of processDescription(), but I can't understand how I can populate the array of range iterator at the init of the _description property for this purpose and how can i get the string to be processed in processDescription().

Thanks for throwing some lights on this.

Upvotes: 2

Views: 2332

Answers (1)

Collin Dauphinee
Collin Dauphinee

Reputation: 13973

Given two iterators that you want to create a range out of, you would just construct a boost::iterator_range and pass the two iterators as constructor arguments.

The below code splits str into three character segments and pushes each segment into ranges.

std::vector<boost::iterator_range<std::string::iterator>> ranges;
std::string str = "abcdefghijk";

auto it = str.begin();
auto lastIt = it;
while (it != str.end())
{
    lastIt = it;
    if (std::distance(it, str.end()) < 3)
        it = str.end();
    else
        std::advance(it, 3);

    ranges.push_back(
        boost::iterator_range<std::string::iterator>(lastIt, it)
    );
}

for (auto segment = ranges.begin(); segment != ranges.end(); ++segment)
    std::cout << std::string(segment->begin(), segment->end()) << std::endl;

Upvotes: 2

Related Questions