Russian Qt Forum

Qt => Интернационализация, локализация => Тема начата: kirill от Сентябрь 24, 2008, 13:29



Название: Читать файлы в разных кодировках
Отправлено: kirill от Сентябрь 24, 2008, 13:29
Есть задача считывать файлы в разных кодировках (UTF-8, ANSI).
Код:
//читаю файл
QByteArray ba;
//поскипано
ba = file.readAll();

Дальше нужно разобрать где какая кодировка. Соответственно для ANSI сделать так
Код:
QTextCodec *codec = QTextCodec::codecForLocale();
QString string = codec->toUnicode(ba);

а для UTF-8 так
Код:
QString string = QString::fromUtf8(ba);

Вопрос в том как понять в какой кодировке файл или QByteArray.


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 13:50
Есть алгоритмы. Берешь из файлика первые n байт и пробуешь в разных кодировках искать в нем осмысленные последовательности, типа "ан" "ов" и пр.


Название: Re: Читать файлы в разных кодировках
Отправлено: kirill от Сентябрь 24, 2008, 13:51
Фигасе.
А нет чего-нибудь Qt-вого типа IsUtf8?


Название: Re: Читать файлы в разных кодировках
Отправлено: kirill от Сентябрь 24, 2008, 14:11
Нашел у китайцев с qtcn.org
Проверка на UTF-8
Код:
bool isUtf8(const char *str)
{
    unsigned int len = strlen (str);
    unsigned int counter = 0;
    unsigned char head = 0x80;
    unsigned char tempStr;
    unsigned int gbNum = 0,utf8Num = 0;
    bool gb2 = FALSE;
   
    for (int i=len-1; i>=0; i--)
    {
        tempStr = (unsigned char)str[ i];
        if (!gb2 && (tempStr>161) && (tempStr<254))
        {
              gb2 = TRUE;
        }
        else
        if (gb2 && (tempStr> 161) && (tempStr<247))
        {
              gbNum++;
              gb2 = FALSE;       
        }
        else
        {
              gb2 = FALSE;   
        }
       
       
        if ((tempStr&0xc0) == 0x80 )
        {
              counter ++;
              head = head>>1;
              head |= 0x80;
        }
        else
        if (counter > 0)
        {
              if ((((head>>1)|0x80)&tempStr) == head)
              {
                  utf8Num++;
                  head = 0x80;
                  counter = 0;
            }
        } else {
              head = 0x80;
              counter = 0;
        }
    }

    if (gbNum*2 <= utf8Num*3)
    {
        return TRUE;
    } else
    {
        return FALSE;
    }
}


Соответственно использую
Код:
QString string;
if (!isUtf8(ba.constData()))
{
   QTextCodec *codec = QTextCodec::codecForLocale();
   string = codec->toUnicode(ba);
}
else
   string = QString::fromUtf8(ba);


Название: Re: Читать файлы в разных кодировках
Отправлено: Alex03 от Сентябрь 24, 2008, 14:14
А кто эти файлы формирует?
А то в UTF-8 можно запихать первым "символом" BOM (byte-order mark).
http://en.wikipedia.org/wiki/Byte_Order_Mark


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 14:19
На сколько я знаю, рекомендуется не пользоваться BOM. Его, кстати, вставляет блокнот в масдае.
Была прожка классная для определения кодировки "Штирлиц", может где-то исходники есть...


Название: Re: Читать файлы в разных кодировках
Отправлено: kirill от Сентябрь 24, 2008, 14:20
Ну мне кажется китайский вариант (если они сами еще откуда-нибудь не утянули) вполне подходит.
Требовать наличия BOM не могу иначе бы потребовал, чтобы все файлы были в UTF и ниип*т.


Название: Re: Читать файлы в разных кодировках
Отправлено: Alex03 от Сентябрь 24, 2008, 14:28
На сколько я знаю, рекомендуется не пользоваться BOM. Его, кстати, вставляет блокнот в масдае.
panter_dsd Для UTF-8 или вообще? И кем рекомендуется? Интересует ссылка с обоснованиями.


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 14:29
В гугле набери "как определить кодировку текста" и будет тебе счастье.


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 14:30
На сколько я знаю, рекомендуется не пользоваться BOM. Его, кстати, вставляет блокнот в масдае.
panter_dsd Для UTF-8 или вообще? И кем рекомендуется? Интересует ссылка с обоснованиями.
К сожалению ссылки нет, так как не помню где читал. Скорее всего где-то в faq'е. Не претендую на достоверность.


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 14:38
Цитировать
Отключайте BOM

При сохранении файла многие текстовые редакторы предлагают флажок «Include Unicode Signature (BOM)», «Add Byte Order Mark» или нечто подобное. Прежде всего убедитесь, что в вашем редакторе это есть. Если похожей настройки не обнаружено (как, например, в «Блокноте») — пользоваться таким редактором для серьёзных задач не стóит. Найдя этот флажок — отключите его.

Byte Order Mark (BOM) — это три служебных байта, которые автоматически записываются в начало документа и обозначают, что он сохранён в кодировке UTF. Подробности можно прочитать в справочнике, а практическая сторона заключается в том, что эти служебные байты в UTF‑8 не являются необходимыми, зато, наоборот, могут ввести в заблуждение некоторые старые браузеры и другие программы.
Взято с http://webmastak.com/article.aspx?id=300 (http://webmastak.com/article.aspx?id=300). Кстати, если захочешь в исходники впихнуть BOM, то обломишься с компилятором.


Название: Re: Читать файлы в разных кодировках
Отправлено: ритт от Сентябрь 24, 2008, 15:00
На сколько я знаю, рекомендуется не пользоваться BOM. Его, кстати, вставляет блокнот в масдае.
panter_dsd Для UTF-8 или вообще? И кем рекомендуется? Интересует ссылка с обоснованиями.

_я_лично_ не рекомендую :)
сохрани сорц в ютф-8 с бом и попробуй скомпилить...расскажешь потом впечатления :)


Название: Re: Читать файлы в разных кодировках
Отправлено: Пантер от Сентябрь 24, 2008, 17:41
Я напоролся один раз, потом мозги включил. :)


Название: Re: Читать файлы в разных кодировках
Отправлено: ритт от Сентябрь 24, 2008, 18:03
я однажды тоже напоролся - минут пять не мог уразуметь откуда гцц такую чушь берёт :)
вдруг резко осенило - полез в настройки - и правда, бом включен по умолчанию...

с тех пор мы с бом по разные стороны баррикад :)


Название: Re: Читать файлы в разных кодировках
Отправлено: Alex03 от Сентябрь 24, 2008, 18:49
Ок, принял к сведению. :)


Название: Re: Читать файлы в разных кодировках
Отправлено: Tonal от Сентябрь 26, 2008, 08:22
Определять можно только статистически, да и то оно не всегда работает.
Интересно, а что за задача стоит? Откуда беруться файлы в разных неизвестных кодировках?

П.С. В одном из проектов кодировка файлов - win1251, но они под контролем свина, который в заголовок вставляет строчку в utf-8. Некоторые редакторы так и открывают в utf-8, без возможности выбрать руками. Заразы!


Название: Re: Читать файлы в разных кодировках
Отправлено: lit-uriy от Сентябрь 26, 2008, 10:01
2 Tonal, да хоть просто текстовый редакор человек пишет, с поддержкой кучи кодировок. (ты и сам на вопрос ответил :) )


Название: Re: Читать файлы в разных кодировках
Отправлено: kirill от Сентябрь 26, 2008, 10:49
2 Tonal, да хоть просто текстовый редакор человек пишет, с поддержкой кучи кодировок. (ты и сам на вопрос ответил :) )

На самом деле это удобнее мне самому. Ну то, что я не завишу от типа кодировки. Файлы я сам составляю, но теоретически, их может составлять сторонний юзер из зимбабве. И вот чтобы ему не париться с кодировками, буду поддерживать сам все что он напишет.


Название: Re: Читать файлы в разных кодировках
Отправлено: Tonal от Сентябрь 26, 2008, 18:31
Вот, чтобы с кодировками не париться, в формат вводят поле для явного указания кодировки.
Ну а в патологических случаях, когда формата как такового нет, или он задан и в нём не предусмотрено указание кодировки - толька статистика + выбор пользователя.