Utf-8 в URI процентное кодирование

0

Я пытаюсь преобразовать коды кода Unicode в кодированные кодовые единицы UTF-8.

Преобразование Unicode → UTF-8, похоже, работает правильно, как показано в некоторых тестах с хинди и китайскими символами, которые корректно отображаются в Notepad++ с кодировкой UTF-8 и могут быть переведены правильно.

Я думал, что процентная кодировка будет такой же простой, как добавление "%" перед каждым модулем кода UTF-8, но это не совсем работает. Вместо ожидаемого % E5% 84% A3, я вижу % xE5% x84% xA3 (для unicode U + 5123).

Изображение 174551

Что я делаю не так?

Добавлен код (обратите внимание, что utf8.h принадлежит библиотеке UTF8-CPP).

#include <fstream>
#include <iostream>
#include <vector>
#include "utf8.h"

std::string unicode_to_utf8_units(int32_t unicode)
{
    unsigned char u[5] = {0,0,0,0,0};
    unsigned char *iter = u, *limit = utf8::append(unicode, u);
    std::string s;
    for (; iter != limit; ++iter) {
        s.push_back(*iter);
    }
    return s;
}

int main()
{
    std::ofstream ofs("test.txt", std::ios_base::out);
    if (!ofs.good()) {
        std::cout << "ofstream encountered a problem." << std::endl;
        return 1;
    }

    utf8::uint32_t unicode = 0x5123;
    auto s = unicode_to_utf8_units(unicode);
    for (auto &c : s) {
        ofs << "%" << c;
    }

    ofs.close();

    return 0;
}
Теги:
utf-8

1 ответ

2
Лучший ответ

Вам действительно нужно преобразовать значения байтов в соответствующие строки ASCII, например:

"é" в UTF-8 - это значение { 0xc3, 0xa9 }. Пожалуйста, не то, что это байты, значения char в C++.

Каждый байт необходимо преобразовать в: "%C3" и "%C9" соответственно.

Лучший способ сделать это - использовать sstream:

std::ostringstream out;
std::string utf8str = "\xE5\x84\xA3";

for (int i = 0; i < utf8str.length(); ++i) {
    out << '%' << std::hex << std::uppercase << (int)(unsigned char)utf8str[i];
}

Или в C++ 11:

for (auto c: utf8str) {
    out << '%' << std::hex << std::uppercase << (int)(unsigned char)c;
}

Обратите внимание, что байты должны быть переданы в int, потому что иначе оператор << будет использовать двоичное значение litteral. Первое кастинг на unsigned char необходимо, потому что иначе знаковый бит будет распространяться на значение int, вызывая вывод отрицательных значений, таких как FFFFFFE5.

  • 0
    Ваш код дает мне результат 0x28fd6c при записи в поток выходного файла.
  • 0
    Это работает правильно, см .: ideone.com/jIq1jf
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню