В настоящее время я работаю над решением проблемы с преобразованием строки UTF-8 в строку UCS-2 с помощью библиотеки icu. Есть несколько способов сделать это в библиотеке, но пока что ни один из них, похоже, не работает, но, учитывая популярность этой библиотеки, я предполагаю, что я делаю что-то не так.
Прежде всего, это общий код. Во всех случаях я создаю и передаю строку на объекте, но пока она не достигнет шагов преобразования, никаких манипуляций не происходит.
В настоящее время используется строка utf-8 — просто «ĩ».
Для простоты я представлю строку, используемую как uniString
в этом коде
UErrorCode resultCode = U_ZERO_ERROR;
UConverter* m_pConv = ucnv_open("ISO-8859-1", &resultCode);
// Change the callback to error out instead of the default
const void* oldContext;
UConverterFromUCallback oldFromAction;
UConverterToUCallback oldToAction;
ucnv_setFromUCallBack(m_pConv, UCNV_FROM_U_CALLBACK_STOP, NULL, &oldFromAction, &oldContext, &resultCode);
ucnv_setToUCallBack(m_pConv, UCNV_TO_U_CALLBACK_STOP, NULL, &oldToAction, &oldContext, &resultCode);
int32_t outputLength = 0;
int bodySize = uniString.length();
int targetSize = bodySize * 4;
char* target = new char[targetSize];
printf("Body: %s\n", uniString.c_str());
if (U_SUCCESS(resultCode))
{
// outputLength = ucnv_convert("ISO-8859-1", "UTF-8", target, targetSize, uniString.c_str(), bodySize, &resultCode);
outputLength = ucnv_fromAlgorithmic(m_pConv, UCNV_UTF8, target, targetSize, uniString.c_str(),
uniString.length(), &resultCode);
ucnv_close(m_pConv);
}
printf("ISO-8859-1 DGF just tried to convert '%s' to '%s' with error '%i' and length '%i'", uniString.c_str(),
outputLength ? target : "invalid_char", resultCode, outputLength);
if (resultCode == U_INVALID_CHAR_FOUND || resultCode == U_ILLEGAL_CHAR_FOUND || resultCode == U_TRUNCATED_CHAR_FOUND)
{
if (resultCode == U_INVALID_CHAR_FOUND)
{
printf("Unmapped input character, cannot be converted to Latin1");
m_pConv = ucnv_open("UCS-2", &resultCode);
if (U_SUCCESS(resultCode))
{
// outputLength = ucnv_convert("UCS-2", "UTF-8", target, targetSize, uniString.c_str(), bodySize, &resultCode);
outputLength = ucnv_fromAlgorithmic(m_pConv, UCNV_UTF8, target, targetSize, uniString.c_str(),
uniString.length(), &resultCode);
ucnv_close(m_pConv);
}
printf("UCS-2 DGF just tried to convert '%s' to '%s' with error '%i' and length '%i'", uniString.c_str(),
outputLength ? target : "invalid_char", resultCode, outputLength);
if (U_SUCCESS(resultCode))
{
pdus = SegmentText(target, pText, SEGMENT_SIZE_UNICODE_MAX, true);
}
}
else
{
printf("DecodeText(): Text contents does not appear to be valid UTF-8");
}
}
else
{
printf("DecodeText(): Text successfully converted to Latin1");
std::string newBody(target, outputLength);
pdus = SegmentText(newBody, pPdu, SEGMENT_SIZE_MAX);
}
Проблема заключается в ucnv_fromAlgorithmic
функция выдает ошибку U_INVALID_CHAR_FOUND
для преобразования ucs-2. Это имеет смысл для ISO-8859-1
Попытка, но не UCS-2.
Другая попытка была использовать ucnv_convert
который вы можете видеть, закомментирован. Эта функция пыталась выполнить преобразование, но не ISO-8859-1
попытаться как следует.
Таким образом, вопрос в том, имеет ли кто-нибудь опыт работы с этими функциями и видит ли что-то неправильное или что-то неверное в предположении преобразования для этого символа?
Вам нужно сбросить resultCode
в U_ZERO_ERROR
перед звонком ucnv_open
, Цитата из руководство:
«Функции ICU, которые принимают ссылку (C ++) или указатель (C) на первый тест UErrorCode, если (U_FAILURE (errorCode)) {немедленно возвращать;}, так что в цепочке таких функций первая, которая устанавливает код ошибки, вызывает следующие, чтобы не выполнять никаких операций «
Других решений пока нет …