从vector <char> </char>创建尽可能长的字符串

时间:2013-01-09 12:30:13

标签: c++ vector iterator

我收到的数据为vector<char>,我需要创建一个string。向量可以包含utf-16个字符(即空字节)并且是固定大小。实际数据用空字节填充到此固定大小。因此,例如,我可以使用以下向量:

\0 a \0 b \0 c \0 d \0 \0 \0 \0

固定大小为12,向量包含utf-16字符串&#34; abcd&#34;用4个空字符填充大小。

由此,我需要实际提取此字符串。我已经有了从utf-16转换为string的代码,我对此感到困惑的是找到没有填充的向量中的字符数(字节)。在上面的示例中,数字为8。

我开始做类似的事情:

std::string CrmxFile::StringFromBytes(std::vector<char> data, int fixedsize) {

    std::vector<char>iterator it = data.rbegin();
    while(it != data.rend() && *it == '\0') {
        it++;
    }

    return std::string(&data[0], fixedsize - (it - data.rbegin());
}

然而,在完整的上下文中,向量包含大量数据,我需要仅使用指定的部分进行上述操作。例如,向量可能包含1000个元素,我需要获取从位置30开始并最多12个字符的字符串。当然,在应用上述逻辑之前,我可以创建另一个向量并将所需的21个字符复制到其中,但我觉得我应该可以直接在给定的向量上做一些事情。然而,我无法理解我与之比较的迭代器。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

现在,这很令人尴尬:vector<char>::iterator显然是一个随机访问迭代器,因此我可以减少它。因此我的方法现在看起来像这样:

std::string CrmxFile::StringFromBytes(std::vector<char> data, int fixedsize) {
    std::vector<char>::iterator begin = data.begin() + start;
    std::vector<char>::iterator end = start + length - 1;
    while(it >= begin  && *it == '\0') {
        it--;
    }

    if(it >= begin) {
        int len = it - begin + 1;
        if(IsUtf8Heuristic(begin, begin + len) {
            return std::string(begin, begin + len);
        }
        else {  //(heuristically this is utf-16)
            len = ((len + 1) >> 1) << 1;
            std::string res;
            ConvertUtf16To8(begin, begin + len, std::back_inserter(res));
            return res;
        }
    }
    else {
        return "";
    }
}

答案 1 :(得分:-1)

根据我的理解,您想从fixedsize中提取最大data的一部分,并删除所有尾随零。从评论中你想要最佳解决方案。

对我来说,如果数据始终采用数组形式,则代码过于复杂。使用指数,他们更自我描述。

std::vector<char> data = ...;
int fixedsize = ...;
int start = ...;

int i = start + fixedsize - 1; // last character that can be in the string
while(i >= start && data[i] == 0) i--; // 'remove' the trailing zeroes
std::string result(&data[start], i - start + 1);

这是最优算法,没有“更优化”的算法(有一个微优化,包括用int而不是char进行测试,即4 {{1}连续)。