Получение идентификатора кодировки по названию
Думаю над следующей задачей
Необходимо осуществить преобразование кодировки текста в UTF-8
Буду использовать функцию MultiByteToWideChar
Один вопрос
В ней надо указывать Code Page исходной кодировки
Я знаю название кодировки (допустим, windows-1251)
Её Code Page можно узнать из таблицы на странице Code Page Identifiers
Но, кодировка то может быть любая
Есть ли какой-то способ по названию кодировки узнать её идентификатор?
Или придётся создавать тот же map с указанием соответствий название-идентификатор?
Вобщем-то, проблему я решил так
codePages["utf-16"] = 1200;
codePages["windows-1250"] = 1250;
codePages["windows-1251"] = 1251;
codePages["koi8-r"] = 20866;
codePages["koi8-u"] = 21866;
codePages["koi8-u"] = 21866;
//если данной кодировки в списке нет
if (codePages.find(from) == codePages.end()) {
AfxMessageBox("Неизвестная кодировка " + from);
return "";
}
главное, чтобы можно было получить Code Page Identifier
Быдлокод детектед.
Дали же тебе в соседней теме аж целых два способа. Нет, млин, мы не ищем лёгких путей. Обязательно надо заговнокодить. Сделай по-нормальному, чёрт возьми, иначе на всю жизнь начинающим останешься.
имеется в виду MLang и libiconv?
а libiconv разве не сторонняя библиотека?
я просто хотел бы обойтись именно встроенными средствами
а по поводу MLang...
ну да, можно выполнить то же самое, написав
static const char szSrc[] = "À�ÂÃÄÅÆÇÈÉÊËÌ";
IMultiLanguage2* mlang;
HRESULT hr;
hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); // init COM
hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (void **)&mlang);
IMLangConvertCharset* pConverter;
hr = mlang->CreateConvertCharset(CP_UTF8, CP_UTF16, 0, &pConverter);
DWORD dwSrcLen = strlen(szSrc);
LPWSTR pDstBuf = new wchar_t[dwSrcLen + 1];
LPWSTR pDst = pDstBuf;
LPCSTR pSrc = szSrc;
DWORD dwConverted = 0;
while (dwConverted < dwSrcLen) {
// Convert 5 bytes at a time
UINT nSrcBytes = min(5, dwSrcLen - dwConverted);
UINT nDstChars = dwSrcLen - dwConverted;
hr = pConverter->DoConversionToUnicode((LPSTR)pSrc, &nSrcBytes, pDst, &nDstChars);
dwConverted += nSrcBytes;
pSrc += nSrcBytes;
pDst += nDstChars;
}
*pDst = L'\0';
_tprintf(L"%d: %s\n", pDst - pDstBuf, pDstBuf);
delete [] pDstBuf;
pConverter->Release();
mlang->Release();
::CoUninitialize();
return 0;
и если сравнить с моим
//выделяем память под wide char строку:
wchar_t *pwText;
pwText = new wchar_t[dwNum];
if(!pwText) {
return "";
delete []pwText;
}
MultiByteToWideChar(codePages[from], 0, str, -1, pwText, dwNum);
//Конвертируем WideString в UTF-8
dwNum = WideCharToMultiByte(CP_UTF8, 0, pwText, -1, NULL, 0, NULL, NULL);
char *Text;
Text = new char[dwNum];
if(!Text) {
return "";
delete []Text;
}
WideCharToMultiByte(CP_UTF8, 0, pwText, -1, Text, dwNum, NULL, NULL);
CString res = CString(Text);
//очищаем выделенную под переменные память
delete []pwText;
delete []Text;
return res;
то у меня куда понятней
шило на мыло?
имеется в виду
codePages["utf-16"] = 1200;
codePages["windows-1250"] = 1250;
codePages["windows-1251"] = 1251;
codePages["koi8-r"] = 20866;
codePages["koi8-u"] = 21866;
codePages["koi8-u"] = 21866;
то это да, тут я принимаю, что это быдлокод
хорошо, допустим, есть
но эта функция вернёт нам <цитирую>:
То есть, она возвращает, в том примере, либо
Locale is: C
либо
Locale is: English_United States.1252
а мне нужно определить charset текста! где в setlocale можно указать текст в качестве входного параметра?
так что это не подходит
могли бы подойти
IMLangConvertCharset::GetDestinationCodePage
или
IMLangCodePages::GetCharCodePages
но это не то
я больше способов не знаю
Набор символов текста надо брать из текста. В HTML он берётся из ответа сервера или meta-тега документа. В других нормальных форматах аналогично. Если кодировка не указана, это неправильный формат.
Если всё же стоит задача работать с неправильными форматами, нужно угадывать набор символов. Или учиться самому, или воспользоваться MLang-ом, который, как говорят, это умеет. Задача решается на основе частотного анализа, просто в случае MLang реализация сидит в системе. Если хочется самому, можно посмотреть в исходниках FAR -- он тоже умеет угадывать наборы символов.
Если набор символов получен в виде идентификатора MIME, его нужно перевести в номер кодовой страницы. Можно или читать реестр самостоятельно, как писал выше, или снова воспользоваться MLang-ом. Прошивать в программе подмножество кодировок -- быдлокод. А если придёт документ в Windows-1257? Отбрасывать "Windows-" и остаток брать как число? А если Big5?
Это то понятно
Прсто с MLang времени пока не было разбираться, как будет - обязательно покопаюсь
Хм, это врят ли
Вообще, ни разу не видел страницы в кодировках, отличных от windows-1251, utf-8, ну и уж ооочень на крайний случай (последний раз видел такую страницу в своей же лабе на первом курсе, которую сам же и делал) koi8-r и иже с ним.
Этот быдлокод, естественно, вариант временный
Нет ничего более постоянного, чем временные решения... А потом мы ещё удивляемся, откуда столько глючных программ.
ну мне всё равно придётся всё переписывать - с MFC на Qt
А потом, обнаружив, что и QT "не подходит", переписать все на C#.
нет C#, как вариант, отметается сразу
думаю, понимаешь, почему :)