0

データを として受け取りvector<char>、そこから を作成する必要がありますstring。ベクトルには utf-16 文字 (ヌル バイト) を含めることができ、固定サイズです。実際のデータは、この固定サイズになるまで null バイトで埋められます。したがって、たとえば、次のベクトルを使用できます。

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

固定サイズは 12 で、ベクトルには utf-16 文字列 "abcd" が含まれ、サイズに合わせて 4 つの null 文字が埋め込まれます。

これから、実際にこの文字列を抽出する必要があります。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

fixedsize質問を理解しているので、 max の一部をから抽出し、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);

これは最適なアルゴリズムであり、「より最適な」アルゴリズムはありません ( ints ではなく sを使用してテストするchar、つまり 4 つcharの s を連続してテストするマイクロ最適化があります)。

于 2013-01-09T20:09:53.127 に答える