Я пытаюсь преобразовать коды кода Unicode в кодированные кодовые единицы UTF-8.
Преобразование Unicode → UTF-8, похоже, работает правильно, как показано в некоторых тестах с хинди и китайскими символами, которые корректно отображаются в Notepad++ с кодировкой UTF-8 и могут быть переведены правильно.
Я думал, что процентная кодировка будет такой же простой, как добавление "%" перед каждым модулем кода UTF-8, но это не совсем работает. Вместо ожидаемого % E5% 84% A3, я вижу % xE5% x84% xA3 (для unicode U + 5123).
Что я делаю не так?
Добавлен код (обратите внимание, что 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;
}
Вам действительно нужно преобразовать значения байтов в соответствующие строки 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
.