Мне нужно конвертировать двухбайтовые символы. В моем особом случае Shift-Jis более удобен, желательно со стандартным C ++.
следующий вопрос оказался без обходного пути:
Двухбайтовые кодировки в MSVC (std :: codecvt): ведущие байты не распознаются
Так есть кто-нибудь с предложением или рекомендацией о том, как обрабатывать это преобразование с помощью стандарта C ++?
Обычно я бы порекомендовал ICU, но для этого одного, использование это слишком много накладных расходов.
Ниже кода есть ссылка на файл, содержащий таблицу преобразования. Загрузите его в вашу программу, например, в массив / вектор uint8_t
с именем convTable (ровно 25088 байт), затем вы можете использовать следующую функцию для преобразования строки ShiftJIS в UTF8 (оба как std::string
):
std::string sj2utf8(const std::string &input)
{
std::string output(3 * input.length(), ' ');
size_t indexin = 0, indexout = 0;
while(indexin < input.length())
{
char group = ((uint8_t)input[indexin]) >> 4;
size_t offset = 0;
if(group == 0x8) offset = 0x100;
else if(group == 0x9) offset = 0x1100;
else if(group == 0xE) offset = 0x2100;
else group = 0;
if(group)
{
offset += (((uint8_t)input[indexin]) & 0xf) << 8;
}
else offset = input[indexin];
indexin++;
if(group && indexin < input.length())
{
offset |= (uint8_t)input[indexin++];
}
offset <<= 1;uint16_t value = (convTable[offset] << 8) | convTable[offset + 1];
if(value < 0x80)
{
output[indexout++] = value;
}
else if(value < 0x800)
{
output[indexout++] = 0xC0 | (value >> 6);
output[indexout++] = 0x80 | (value & 0x3f);
}
else
{
output[indexout++] = 0xE0 | (value >> 12);
output[indexout++] = 0x80 | ((value & 0xfff) >> 6);
output[indexout++] = 0x80 | (value & 0x3f);
}
}
output.resize(indexout);
return output;
}
Функция не проверяет, являются ли ввод действительными данными ShiftJIS, недопустимые символы будут генерировать пробелы в выводе UTF8 (не только из-за ' '
в коде файл данных тоже сделан таким образом)
Файл:
Скачать: http://www.filedropper.com/shiftjis
Сгенерировано из: ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT
Содержание:
Двухбайтовые исходные значения Unicode с прямым порядком байтов (более двух байтов здесь не требуется)
Первые 256 символов (512 байт) для однобайтовых символов ShiftJIS, значение 0x20 для недопустимых.
Тогда 3 * 256 * 16 символов для групп 0x8 ???, 0x9 ??? и 0xE ???
= 25088 байт
Других решений пока нет …