Преобразовать строку в escape-последовательность UTF-8 - PullRequest
1 голос
/ 10 ноября 2011

В моей программе на C ++ я хочу преобразовать строку std: string так:

abc €

в escape-последовательность UTF-8:

abc%20%E2%82%AC

И мне нужно, чтобы он был независимым от платформы! Все, что я нашел, это решения, работающие только на Windows. Там должно быть решение там, верно?

Ответы [ 3 ]

4 голосов
/ 10 ноября 2011

Мне кажется, это довольно просто.Ваша строка представляет собой последовательность байтов.Определенные байтовые значения (большинство, фактически, но не самые распространенные) недопустимы и должны быть заменены трехсимвольной последовательностью '%', за которой следуют два шестнадцатеричных символа, представляющих байтовое значение.Так что-то вроде:

std::string
toEscaped( std::string const& original )
{
    std::string results ;
    for ( std::string::const_iterator iter = original.begin();
            iter != original.end();
            ++ iter ) {
        static bool const allowed[] =
        {
            //  Define the 256 entries...
        };
        if ( allowed[static_cast<unsigned char>(*iter)] ) {
            results += *iter;
        } else {
            static char const hexChars[] = "0123456789ABCDEF";
            results += '%';
            results += hexChars[(*iter >> 4) & 0x0F];
            results += hexChars[(*iter     ) & 0x0F];
        }
    }
    return results;
}

должно сработать.

3 голосов
/ 10 ноября 2011

До C ++ 11 в стандарте не было обязательной поддержки UTF-8.

Здесь есть два шага:

  • конвертировать в UTF-8 (если он уже не в UTF-8)
  • URL-экранирование результата (обновление: Джеймс Канзе освещает эту часть)

Ни один из них не является особенно трудным для написания для себя портативно, если вы знаете, какой кодировкой символов используется входная строка [*]. Это означает, что другие люди делали это раньше, вам не нужно писать это самостоятельно. Если вы будете искать их отдельно, вам, возможно, повезет с поиском независимого от платформы кода для каждого шага.

Обратите внимание, что есть два разных способа URL-экранирования пробела: либо +, либо %20. В вашем примере используется %20, поэтому, если это важно для вас, не используйте случайно подпрограмму экранирования URL, которая делает другое.

[*] Это не ISO-Latin-1, поскольку на нем нет знака евро [**], но это может быть Windows CP-1252.

[**] Если это не было добавлено недавно. В любом случае, ваш пример кодирует знак евро в виде байтов UTF-8 0xE2 0x82 0xAC, которые представляют кодовую точку Unicode 0x20AC, а не кодовую точку 0x80, которую он имеет в CP1252. Таким образом, если изначально это была однобайтовая кодировка, то очевидно, что интеллектуальное преобразование однобайтовой кодировки в кодировку юникода было применено на этом пути. Можно сказать, что есть три шага:

  • преобразовать std::string в кодовые точки Unicode (зависит от входной кодировки).
  • конвертировать Unicode в UTF-8
  • URL-экранирование UTF-8
2 голосов
/ 10 ноября 2011

Для независимой от платформы многофункциональной обработки Unicode стандартной библиотекой "де-факто" является ICU, которая используется многими компаниями из списка Fortune 500 и проектами с открытым исходным кодом ... Лицензия имеет открытый код и удобна для использования в коммерческих разработках

Это может быть излишним, если вы просто хотите использовать некоторые простые преобразования, хотя ...

http://site.icu -project.org

Если вам просто нужнопростая переносимая библиотека utf-8 c ++, которую вы можете попробовать http://utfcpp.sourceforge.net

hth

...