Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  04:20[Войти] | [Зарегистрироваться]
Ответ на вопрос № 83812

06-05-2022 16:12
Добрый день уважаемому сообществу !
Помогите разобраться со следующей проблемой.

На обработку поступает массив строк. Нужно  определить кодировку строк - либо ANSI, либо Unicode.

Работа идет в среде Embarcadero Delphi RAD Studio 10.

Этот массив строк хранится в компоненте TStringList.
Если строки вводятся из файла прямо в TStringList, то для этого случая имеется демонстрационный код, работающий на ура :

procedure TForm2.Btn1Click(Sender: TObject);
var
  ListStr : TStringList;
  StrNameCod : UnicodeString;
  LEncoding : TEncoding;
begin
ListStr := TStringList.Create();
ListStr.Clear();

  case RG.ItemIndex of
    0 : ListStr.LoadFromFile( 'c:\ ... ' ); // Вводим файл с текстом в кодировке ANSI
    1 : ListStr.LoadFromFile( 'c:\ ... ' ); // Вводим файл с текстом в кодировке Unicode
  end;

LEncoding := ListStr.Encoding;
StrNameCod := LEncoding.EncodingName; // получаем имя кодировки текста

Memo1.Clear();
Memo1.Lines.AddStrings( ListStr );

Memo2.Clear();
Memo2.Lines.Add( StrNameCod ); // выводим на отображение имя кодировки текста

ListStr.Free();
end;


  А вот в случае, если строки в TStringList загружаются не прямо из файла, а из какого-то стороннего источника
( допустим - из другого компонента ), то свойство ListStr.Encoding  не работает :

procedure TForm2.Btn2Click(Sender: TObject);
var
  ListStr : TStringList;
  StrNameCod : UnicodeString;
  i : Integer;
  LEncoding : TEncoding;
begin
// Сперва загружаем из файла строки в Memo, а затем переписываем их в StringList
//  ( имтация передачи в StringList из стороннего источника )
case RG.ItemIndex of
  0 : Memo1.Lines.LoadFromFile( 'c:\ ... ' ); // Вводим файл с текстом в кодировке ANSI
  1 : Memo1.Lines.LoadFromFile( 'c:\ ... ' ); // Вводим файл с текстом в кодировке Unicode
end;

LEncoding := TEncoding.Create();

ListStr := TStringList.Create();
ListStr.Clear();

ListStr.AddStrings( Memo1.Lines );

// for i := 0 to Memo1.Lines.Count - 1 do
//  ListStr.Add( Memo1.Lines.Strings[ i ] );

LEncoding := ListStr.Encoding;

// StrNameCod := LEncoding.EncodingName;
StrNameCod := ListStr.Encoding.EncodingName;
// StrNameCod := Memo1.Lines.Encoding.EncodingName;

Memo2.Clear();
Memo2.Lines.Add( StrNameCod );

LEncoding.Free();
ListStr.Free();
end;


При присвоении StrNameCod значения непосредственно от ListStr.Encoding.EncodingName, либо через LEncoding.EncodingName
приложение аварийно вылетает с исключением.
  При таких  условиях ( строки вводятся не из файла ) свойство ListStr.Encoding не работает, или я чго-то не так делаю ?
Починить как-то можно ?


[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

05-10-2022 05:38
Python, я в силу сложившихся обстоятельств очень долго не заглядывал сюда, и только сейчас обнаружил ваш пост.
сам факт наличия BOM попортит логику работы программы и нервы какому-то другому программисту, например, лично я уже кушал проблему, что программы с .h файлами на сишечке не всеми компиляторами собираются, если в начале .h файла есть BOM - как раз потому, что BOM после обработки препроцессором попадает чёрт знает куда и ломает работу последующих модулей...
    Мне интересна проблема, изложенная вами в цитате, поскольку и сам работаю с С++, хотя это и не имеет прямое отношение к обсуждаемому.
А что, если для исключения описанной проблемы сборки компиляторами придерживаться жесткого правила - все собираемые файлы должны быть в кодировке ANSI, пусть даже для этого и придется их перевести в таковую кодировку вручную ?

21-08-2022 04:54 | Комментарий к предыдущим ответам
Вся беда в том, что многие файлы "собираются" из кучи других файлов методов include (прямого включения), такие как конфиги, PHP скрипты и куча всего остального. Потому, оказывается, что BOM для таких файлов вреден. Ну и плюс линуксоиды воду мутят, будучи уверены, что "раз в нашей ОС, занимающей 2% рынка по дефолту UTF-8, то и нечего указывать его и баловаться со всякими BOM, если в файле первые, скажем, 1килобайт текста декодируются как UTF-8 - значит, весь файл UTF-8 и весь сказ".
Понятно, что точка зрения очень сильно так себе, но проблема с тем, что действительно не во всех файлах есть BOM и не везде его в принципе можно внедрить отсаётся. Так, из-за того, что при прямом склеивании BOM окажется где-то внутри файла, сам факт наличия BOM попортит логику работы программы и нервы какому-то другому программисту, например, лично я уже кушал проблему, что программы с .h файлами на сишечке не всеми компиляторами собираются, если в начале .h файла есть BOM - как раз потому, что BOM после обработки препроцессором попадает чёрт знает куда и ломает работу последующих модулей... правда, есть обход: первую строчку файла оставлять пустой, но это не всегда выход.
Так что такие дела, полагаться на BOM не стоит, но и пагубно считать всё подряд UTF-8 тоже неверно. Лучше дать право пользователю выбирать, как в Sublime: кодировка по умолчанию (UTF-8) и кодировка отката (Fallback encoding), когда не удаётся декодировать файл как UTF-8 - используем CP-1251. Ну либо совсем просто: всё, что не имеет BOM - CP-1251, пока пользователь не поменяет своё мнение.

16-05-2022 23:54 | Комментарий к предыдущим ответам
KotAlex, это файлы, сформированные различными программами, например, логи. А так же, всевозможные скрипты, xml, json. Я лишь хотел обратить внимание, что BOM - не 100% гарантия. Возможно, автор вопроса с такими файлами не работает.

15-05-2022 09:39 | Сообщение от автора вопроса
Из моего опыта множество Unicode файлов не содержат BOM.
  Разве ?????
Я вот беру первый же попавшийся под руку простой текстовый файл с текстом в Unicode и смотрю его в Total Kommander по F3 в режиме отображения в  шестнадцатиричном коде - при этом ну очень явно видны два самых первых байта в начале файла, не имеющие никакого отношения к тексту. Значения этих байтов, правда, - лес темный, но в контексте данного обсуждения это и не имеет никакого значения ...

12-05-2022 02:21 | Комментарий к предыдущим ответам
Из моего опыта множество Unicode файлов не содержат BOM. Думаю, что надёжнее "огород" со статистикой и (или) анализом. Например, на последовательности, которые присущи определенной кодировке.

07-05-2022 09:56 | Сообщение от автора вопроса
Подозреваю, что после чтения из файла кодировка правильно определяется, потому что в файле есть BOM (Byte Order Mark — несколько байт в начале файла, указывающих на использованную кодировку). Проверьте свои файлы, с которыми всё нормально работает низкоуровневым вьюером).
  Да, все именно так и обстоит. Можно, к примеоу, посмотреть текстовый файл с кодировкой Unicode в Total Kommander по F3 в шестнадцатиричном коде - видно, что два первые байта не имеют отношения к тексту.
  Именно поэтому и имеется возможность формально определить кодировку по этим байтам, но только при вводе из файла !
Если вводим отдельные строки в Unicode, то такого формального признака нет, определять нечем ...

до выполнения чтения из файла или потока,значение свойства Encoding равно nil, поэтому и исключение вылетает. Исключение какое? Если Access violation, то стопудово в этом причина?
Да, вы правы. Действительно, свойство Encoding равно nil изначально, поэтому, если нет ввода из файла, то при обращении к нему и вылетает исключение именно ACCESS VIOLATION.
  В-общем, жаль. Так хотелось иметь какой-то формальный признак наличия кодировки Unicode, а не городить самому огород с распознаванием кодировки ...
Спасибо за ответ.

06-05-2022 16:36
Подозреваю, что после чтения из файла кодировка правильно определяется, потому что в файле есть BOM (Byte Order Mark — несколько байт в начале файла, указывающих на использованную кодировку). Проверьте свои файлы, с которыми всё нормально работает низкоуровневым вьюером).

Хм... читайте хелп — источник знаний :-)

Encoding is a read-only property that contains the value of the character encoding detected when the LoadFromStream or LoadFromFile methods are called. If a file or stream does not contain a BOM (the encoding value cannot be detected) then Encoding is set to the value specified in the DefaultEncoding property.

То есть, у TStrings есть свойство только для чтения Encoding, которое содержит кодировку, определенную при выполнении методов LoadFromStream или LoadFromFile. Если в файле или потоке отсутствует BOM, в Encoding заносится значение, определенное в свойстве DefaultEncoding.

Исходников Эмбаркадеры нет сейчас под рукой, но, подозреваю, что до выполнения чтения из файла или потока,значение свойства Encoding равно nil, поэтому и исключение вылетает. Исключение какое? Если Access violation, то стопудово в этом причина?

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Какой месяц идет после марта?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования