我收到的数据为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个字符复制到其中,但我觉得我应该可以直接在给定的向量上做一些事情。然而,我无法理解我与之比较的迭代器。任何帮助表示赞赏。
答案 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}连续)。