Обычно я бы рекомендовал 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
Содержание:
Два байта большой Endian значения сырой Юникода (более чем в два байта не нужна)
Первые 256 символов (512 байт) для отдельных байт ShiftJIS символов, значение 0x20 для недопустимых.
Затем 3 * 256 * 16 символов для групп 0x8 ???, 0x9 ??? и 0xE ???
= 25088 байт
«Лучше обращаться» за то, что именно? Только одно направление? (ShitJIS => что-то, но не somethingelse => ShiftJIS) – deviantfan
Sry, для отображения в UTF-8, например. Только в одном направлении. Это было бы хорошо знать. – bob