如何迭代128位块中的字符串?

时间:2012-11-06 16:54:14

标签: c++ iterator stdstring

我有一个函数可以处理来自任意长度字符串的128位数据块。如果字符串不能均匀地分成128位的块,则会相应地填充它。

目的是转换输入函数的字符串中的数据。

我最初想过在字符串中循环一个这样的:

//This might have stupid errors.  Hopefully it stillg gets the point across.
for (int i = 0; i < strn.size(); i += 16)
{
    string block = strn.substr(i, i + 15);
    strn.replace(i, i + 15, block);
}

我想这可行,但我认为必须有更优雅的方式来做到这一点。想到的一个想法是将strn封装在一个类中并实现我自己的迭代器,它可以以128位块的形式读取其内容。这很有吸引力,因为构造函数可以处理填充,我当前使用的一些函数可以是私有的,从而避免了潜在的误用。这看起来像是一种富有成效的方法吗?如果是这样,那么如何实现自己的迭代器呢?我非常欢迎详细的解释,因为我对C ++缺乏经验。

还有其他的,或许更好的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

有很多方法。其中一个更简单明了的就是这样: 你可以创建自己的类型大小正好128位;简单的struct将完成这项工作。

typedef struct
{
    char buf[16];
} _128bit;

并使用它来迭代你的字符串。 将字符串的开头强制转换为此结构类型:_128bit* start = (_128bit*)buffer;并使用积分指针算法开始迭代它。 start上的所有操作都将根据其大小进行操作。例如。 ,start++将向前移动128位; start--将移回128位。一旦您处于所需位置,将其重铸为所需类型并执行操作。

答案 1 :(得分:1)

我可能会用迭代器而不是索引来做这个,仍然使用你自己的for循环:

const int NUM_BITS_IN_CHUNK = 128;
const int CHUNK_SIZE = NUM_BITS_IN_CHUNK / CHAR_BIT;

for(std::string::const_iterator iter = str.begin(); iter < str.end(); iter += CHUNK_SIZE)
{
    your_func(iter, iter + CHUNK_SIZE);
}

boost :: iterator_adaptor代码看起来像这样。请注意,为了简单起见,我只获得每个块四个字节而不是16个字节。:

#include <iostream>
#include <string>

#include <boost/iterator_adaptors.hpp>

struct string_chunk_iterator : public boost::iterator_adaptor<string_chunk_iterator, std::string::const_iterator>
{
    string_chunk_iterator(const std::string::const_iterator& base) : iterator_adaptor(base) { }

private:
    friend class boost::iterator_core_access;
    void increment() { this->base_reference() = this->base() + 4; }
    void advance(typename iterator_adaptor::difference_type n)
    {
        this->base_reference() = this->base() + (4 * n);
    }
};

int main()
{
    const std::string tester(20, 'A');

    string_chunk_iterator iter(tester.begin());
    string_chunk_iterator str_end(tester.end());

    for(; iter != str_end; ++iter)
    {
        std::string chunk(&*iter, &*(iter + 1));

        std::cout << chunk << std::endl;
    }

    return 0;
}