Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Получение идентификатора кодировки по названию

5.7K
02 августа 2011 года
Lindemann66
193 / / 21.07.2011
Всем привет!

Думаю над следующей задачей
Необходимо осуществить преобразование кодировки текста в UTF-8

Буду использовать функцию MultiByteToWideChar

Один вопрос

В ней надо указывать Code Page исходной кодировки
Я знаю название кодировки (допустим, windows-1251)
Её Code Page можно узнать из таблицы на странице Code Page Identifiers
Но, кодировка то может быть любая
Есть ли какой-то способ по названию кодировки узнать её идентификатор?
Или придётся создавать тот же map с указанием соответствий название-идентификатор?
5.7K
02 августа 2011 года
Lindemann66
193 / / 21.07.2011
нет нет, нужна именно кодировка
Вобщем-то, проблему я решил так
Код:
map<CString, int> codePages;
    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 "";
    }
316
02 августа 2011 года
Alm3n
889 / / 29.05.2009
setlocal и возвращал кодировку, если вторым параметром Null передать.
5.7K
02 августа 2011 года
Lindemann66
193 / / 21.07.2011
я почитаю, может и подойдёт
главное, чтобы можно было получить Code Page Identifier
10
02 августа 2011 года
Freeman
3.2K / / 06.03.2004
Цитата: Lindemann66
Вобщем-то, проблему я решил так


Быдлокод детектед.

Дали же тебе в соседней теме аж целых два способа. Нет, млин, мы не ищем лёгких путей. Обязательно надо заговнокодить. Сделай по-нормальному, чёрт возьми, иначе на всю жизнь начинающим останешься.

5.7K
03 августа 2011 года
Lindemann66
193 / / 21.07.2011
Цитата: Freeman
Дали же тебе в соседней теме аж целых два способа.


имеется в виду MLang и libiconv?
а libiconv разве не сторонняя библиотека?
я просто хотел бы обойтись именно встроенными средствами

а по поводу MLang...
ну да, можно выполнить то же самое, написав

Код:
// "&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;" in UTF-8
    static const char szSrc[] = "&#195;€&#195;&#65533;&#195;‚&#195;&#402;&#195;„&#195;…&#195;†&#195;‡&#195;&#710;&#195;‰&#195;&#352;&#195;‹&#195;&#338;";

    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;


и если сравнить с моим
Код:
DWORD dwNum = MultiByteToWideChar(codePages[from], 0, str, -1, NULL, 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;


то у меня куда понятней
шило на мыло?

Цитата: Freeman
Быдлокод детектед.


имеется в виду

 
Код:
map<CString, int> codePages;
    codePages["utf-16"] = 1200;
    codePages["windows-1250"] = 1250;
    codePages["windows-1251"] = 1251;
    codePages["koi8-r"] = 20866;
    codePages["koi8-u"] = 21866;
    codePages["koi8-u"] = 21866;
?

то это да, тут я принимаю, что это быдлокод
хорошо, допустим, есть
 
Код:
setlocale(LC_ALL,NULL);


но эта функция вернёт нам <цитирую>:
Цитата:
If the value of this parameter is NULL, the function does not make any change to the current locale, but the name of the current locale is returned by the function.


То есть, она возвращает, в том примере, либо
Locale is: C
либо
Locale is: English_United States.1252

а мне нужно определить charset текста! где в setlocale можно указать текст в качестве входного параметра?
так что это не подходит

могли бы подойти
IMLangConvertCharset::GetDestinationCodePage
или
IMLangCodePages::GetCharCodePages
но это не то

я больше способов не знаю

10
03 августа 2011 года
Freeman
3.2K / / 06.03.2004
Цитата: Lindemann66
а мне нужно определить charset текста!


Набор символов текста надо брать из текста. В HTML он берётся из ответа сервера или meta-тега документа. В других нормальных форматах аналогично. Если кодировка не указана, это неправильный формат.

Если всё же стоит задача работать с неправильными форматами, нужно угадывать набор символов. Или учиться самому, или воспользоваться MLang-ом, который, как говорят, это умеет. Задача решается на основе частотного анализа, просто в случае MLang реализация сидит в системе. Если хочется самому, можно посмотреть в исходниках FAR -- он тоже умеет угадывать наборы символов.

Если набор символов получен в виде идентификатора MIME, его нужно перевести в номер кодовой страницы. Можно или читать реестр самостоятельно, как писал выше, или снова воспользоваться MLang-ом. Прошивать в программе подмножество кодировок -- быдлокод. А если придёт документ в Windows-1257? Отбрасывать "Windows-" и остаток брать как число? А если Big5?

5.7K
03 августа 2011 года
Lindemann66
193 / / 21.07.2011
Цитата: Freeman
Набор символов текста надо брать из текста.



Это то понятно

Прсто с MLang времени пока не было разбираться, как будет - обязательно покопаюсь

Цитата: Freeman
А если придёт документ в Windows-1257


Хм, это врят ли
Вообще, ни разу не видел страницы в кодировках, отличных от windows-1251, utf-8, ну и уж ооочень на крайний случай (последний раз видел такую страницу в своей же лабе на первом курсе, которую сам же и делал) koi8-r и иже с ним.
Этот быдлокод, естественно, вариант временный

10
03 августа 2011 года
Freeman
3.2K / / 06.03.2004
Цитата: Lindemann66
Этот быдлокод, естественно, вариант временный


Нет ничего более постоянного, чем временные решения... А потом мы ещё удивляемся, откуда столько глючных программ.

5.7K
04 августа 2011 года
Lindemann66
193 / / 21.07.2011
Цитата: Freeman
Нет ничего более постоянного, чем временные решения... А потом мы ещё удивляемся, откуда столько глючных программ.



ну мне всё равно придётся всё переписывать - с MFC на Qt

260
04 августа 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: Lindemann66
ну мне всё равно придётся всё переписывать - с MFC на Qt



А потом, обнаружив, что и QT "не подходит", переписать все на C#.

5.7K
04 августа 2011 года
Lindemann66
193 / / 21.07.2011
Цитата: Ramon
А потом, обнаружив, что и QT "не подходит", переписать все на C#.



нет C#, как вариант, отметается сразу
думаю, понимаешь, почему :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог