0

我有一个字符串,其中包含一些二进制数据。xml 格式的字符串,所以在处理它之前,我需要将二进制数据转换为 base64 格式。我正在使用一个名为 findXMLTag 的函数,该函数将在给定包含它的 xml 标记的情况下找到数据的开始和结束位置。现在我可以将该数据转换为 base64,但在用新的 base64 数据替换旧的二进制数据时遇到问题。

问题是我不能使用任何类型的字符串,因为当它找到一个空字符时,它会将其视为字符串的终止点,但事实上,因为我在字符串中存储了二进制数据,所以空字符可以是一部分我的二进制数据。

所以我想我正在寻找某种二进制替换,但我不知道如何使它工作。提前感谢您的任何帮助。

这是我用来定位 xml 字符串中数据的开始和结束的代码。

std::vector<TForm1::Pair> TForm1::findXMLTag(char *XMLString, char* XMLTag, int XMLSize)
{
    void *found = XMLString;
    int XMLTagLen = strlen(XMLTag);
    std::vector<TForm1::Pair> result;
    TForm1::Pair pair;
    AnsiString XMLTagEnd = "</";
    XMLTagEnd += &XMLTag[1];

    while(found = memmem(XMLString, XMLSize - ((char*)found - XMLString), XMLTag, XMLTagLen))
    {
        if(found == NULL)
            return result;

        found = (char*)found + XMLTagLen;

        pair.start = int((char*)found - XMLString);

        found = memmem(found, XMLSize - ((char*)found - XMLString), XMLTagEnd.c_str(), XMLTagEnd.Length());

        pair.end = int((char*)found - XMLString);

        found = (char*)found + XMLTagEnd.Length();

        result.push_back(pair);
    }

    return result;
}
4

3 回答 3

2

将您的 C 风格答案翻译成 C++,我们只剩下一个安全(对于有效索引)、高效且可读的单行代码:

std::string binary_replace(
    std::string const& bin, unsigned bin_start, unsigned bin_end,
    std::string const& replace_with
) {
    assert(bin_start < bin.size() and bin_end < bin.size());
    return bin.substr(0, bin_start) + replace_with + bin.substr(bin_end);
}

为此目的使用该replace函数可以使这变得更加简单:

std::string binary_replace(
    std::string bin, unsigned bin_start, unsigned bin_end,
    std::string const& replace_with
) {
    assert(bin_start < bin.size() and bin_end < bin.size());
    return bin.replace(bin_start, bin_end - bin_start, replace_with);
}

(注意bin这里是按值传递的,因为replace修改了它。)

本质上,C++ 中的大多数 C 字符串函数都有一个直接替代品——在这种情况下,请查看.std::basic_string::substr

于 2013-10-21T23:03:24.160 回答
1

这是一个可能对您有所帮助的独立示例。请注意,没有错误或边界检查,它只是为了演示一个概念。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// stub for real base64_encode
std::string base64_encode(const string &data)
{
    return "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
}

// search without terminating on NULL
size_t binary_find(const string &str, size_t offset, const string &s)
{
    for (size_t i=offset; i<str.length(); i++)
        if (str.compare(i, string::npos, s) == 0)
            return i;
    return string::npos;
}

int main()
{
    string tag = "<data>";
    string endtag = "</data>";
    string xml("<data>\0\0\0\0\0\0\0\0\0\0</data>", 23);
    size_t start = xml.find(tag) + tag.length();
    size_t end = binary_find(xml, start, endtag);
    string binary = xml.substr(start, end-start);
    string base64 = base64_encode(binary);
    xml.replace(start, end-start, base64);
    cout << xml << endl;
}
于 2013-10-21T23:49:18.533 回答
-1
char *binary_replace(char *binString,  int _strlen, int binDataStart, int binDataEnd, char* replaceWith)
{
    char *buffer = (char*)malloc( (strlen(replaceWith)+(_strlen - (binDataEnd-binDataStart)))*sizeof(char) );

    memcpy(buffer, binString, binDataStart);

    strcat(buffer, replaceWith);

    memmove(buffer+binDataStart+strlen(replaceWith), binString+binDataEnd, _strlen - binDataEnd);

    return buffer;
}

我知道这不是 c++,但它解决了我的问题。

于 2013-10-21T22:41:01.040 回答