0

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

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

固定大小为 12,向量包含 utf-16 字符串“abcd”,用 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 个字符复制到其中,但我觉得我应该可以直接在给定的向量上做一些事情。然而,我无法掌握我正在与什么进行比较的迭代器。任何帮助表示赞赏。

4

2 回答 2

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 "";
    }
}
于 2013-01-10T10:49:41.763 回答
-1

据我了解这个问题,您想从中提取 max 的一部分fixedsizedata并擦除所有尾随零。从您想要最佳解决方案的评论中。

对我来说,如果数据始终采用数组形式,那么您的代码就过于复杂了。使用索引,它们更能自我描述。

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);

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

于 2013-01-09T20:09:53.127 回答