1

通常どおり文字と数字を含む std::string がありますが、すべての句読点 (角かっこ、角かっこ、コンマ、コロンなど) は ASCII 表現 ( %28%29%2Cなど%3A) です。

文字列を解析し、「通常の」文字をそのままにして、16 進数値を ASCII 表現に変換する最速の方法は何でしょうか?

4

3 に答える 3

2

たとえば、関数を使用して文字findを検索できます。'%'次の 2 文字が 16 進数の場合は、3 文字を実際の文字に置き換えます。を見つけている間、これらすべてをループで実行します'%'

インプレース置換を行う代わりに、文字列を反復処理して、通常の文字を別の文字列に追加し、に到達し'%'たら、それが有効な URL エスケープであることを確認し、適切な文字を出力文字列に追加することができます。

于 2012-07-31T10:17:54.513 に答える
1

libcurl にはcurl_easy_unescape関数があります。

char *curl_easy_unescape( CURL * curl , char * url , 
        int inlength , int * outlength );

この関数は、指定された URL エンコードされた入力文字列を「プレーン文字列」に変換し、割り当てられたメモリ領域に返します。URL エンコードされたすべての入力文字 (%XX、XX は 2 桁の 16 進数) は、バイナリ バージョンに変換されます。

于 2012-07-31T10:19:56.403 に答える
0

インプレース バージョンは次のとおりです。

void unescape(std::string & s)
{
    for (std::size_t r = 0, w = 0; r != s.size(); )
    {
        char digit;

        if (s[r] != '%')
        {
            ++r;
            ++w;
        }
        else if (r + 1 < s.size() && s[r + 1] == '%')
        {
            r += 2;
            ++w;
        }
        else if (r + 2 < s.size()) && is_hex(s, r + 1, digit))
        {
            s[w] = digit;
            ++w;
            r += 3;
        }
        else
        {
            // error, throw exception?
        }
    }

    s.erase(s.begin() + r, s.end());
}

bool is_hex(std::string const & s, std::size_t offset, char & result)
{
    unsigned char d1, d2;
    if (hex_digit(s[offset], d1) && hex_digit(s[offset + 1], d2))
    {
        result = d1 * 16 + d2;
        return true;
    }
    return false;
}

bool hex_digit(char c, unsigned char & value)
{
    if (c >= '0' && c <= '9') { value = c - '0'; return true; }

    if (c >= 'a' && c <= 'f') { value = c - 'a' + 10; return true; }

    if (c >= 'A' && c <= 'F') { value = c - 'A' + 10; return true; }

    return false;
}
于 2012-07-31T10:48:49.557 に答える