![]() |
|
![]() ![]() ![]() |
|
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Доброго времени!
Есть файл, в котором записана текстовая информация. Вопрос: как узнать в какой кодировке (ANSI, UTF8) записана информация, чтобы корректно ее прочитать и вывести? |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
Часто файлы UTF8 содержат BOM . По нему можно определить. Если же нету BOM, и скажем английский текст в файле, то он будет совпадать с ANSI по содержимому и будет неотличим.
Добавлено через 2 минуты и 19 секунд Кроме того правильные текстовые файлы должны описывать свою кодировку. Например XML файлы имеют специальный атрибут для описания кодировки. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Но файл именно текстовый и без BOM.
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
Гарантированного способа нет. Можно вероятностно по статистике символов. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Я так посмотрел на файлы, сохраненные в разных кодировках, и увидел, что в UTF8 латинские символы хранятся в одном байте и имеют один код по сравнению с ANSI. В то время как русские символы хранятся в двух байтах и имеют другой код. Из этого выходит вывод - файл с латиницей можно открывать в любой кодировке. Распознать UTF8 можно, если в файле есть кириллица. Только вот как определить текущий байт: является ли он автономным или же он часть группы из двух байтов?
|
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 48 Всего: 223 |
Для UTF8 все байты, входящие в многобайтовые последовательности (да, там могут быть и более чем 2 байта на Unicode символ) имеют единичный старший бит (т.е. коды 0x80-0xFF) |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
Не только кириллицей отличаются. Совпадают первые 127 символов. Правило такое. Если это UTF8, то символы должны соответствовать правилам из таблички http://ru.wikipedia.org/wiki/UTF-8 Нужно прочитать все символы и проверить на верность. Если хоть 1 символ не про правилам записан, то это ANSI, хотя теоретически можно написать такой текст, который будет распознаваться как UTF-8 но будет на самом деле ANSI. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
livo |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Так, но не совсем. Младшие биты тоже могут быть единичными:
Вот написал функцию, которая должна распознавать файл по указанному пути:
Но вот не пашет чего-то. Где баг? |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
инкремент переменной i . Если мы прошли 2-4 байта, то нужно смещаться соответственно на 2-4 байта, а не на 1 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
livo |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Нет, в моей функции другая логика предполагалась: нужно было найти всего одно совпадение порядка следования байтов, характерного для UTF8, чтобы в итоге сказать, что файл именно в такой кодировке. Кстати, как думаете, корректен ли такой подход? Я несколько изменил функцию; она работает, но если кто что заметит, буду благодарен за сообщение.
|
||||
|
|||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 48 Всего: 223 |
Ну и что? Старшие то обязаны быть единичными. Одного совпадения не достаточно. В принципе не сущеcтвует способа отличить файл в UTF8 от файла в любой другой однобайтовой CP (точнее, всегда найдется последовательность, которая будет валидна и как UTF8 и как однобайтовая CP, например cp1255) Максимум можно просканировать весь файл и убедится, что с точки зрения кодирования UTF8 он правильный (это кстати будет так и для любого чисто английского текста). Минимум можно найти в файле любой байт с старшим битом, и сказать, что это UTF8 Ваш подход - это нечто среднее Кстати, функцию можно сделать проще
|
|||
|
||||
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Я согласен, что нужно прогнать по всему файлу, чтобы составить представление о кодировке, так как моя функция анси-файл распознает как ютф. Не все файлы, но был встречен такой.
xvr, спасибо за оптимизацию; изменил свою функцию в соответствии с вашим кодом:
Это сообщение отредактировал(а) livo - 12.5.2012, 12:34 |
|||
|
||||
artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Ещё хорошо бы было сначала проверить файл на наличие BOM, а уже потом его анализировать.
-------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 48 Всего: 223 |
Бывают UTF8 файлы без BOM (равно как и Unicode без него же) |
|||
|
||||
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Да, согласен. Только вот почему-то не распознается у меня второй байт триады маркера.
Хотя в том же Листере видно код BB. |
|||
|
||||
artsb |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Я знаю ![]() Т.е. это я описал последовательность действий одного алгоритма )
Странно... У меня всё работало. Попробуйте так:
-------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||
|
|||||
livo |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 104 Регистрация: 14.10.2007 Репутация: 1 Всего: 1 |
Фууух, разобрался. Не зря оказывается компилятор предупреждал о сравнении signed и unsigned переменных.
Вобщем все заработало, как только я дописал оператор приведения типа:
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++ Builder" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C++ Builder | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |