Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Как прибавить BOM-заголовок к строке AnsiString?  [new]
crossa
Member

Откуда:
Сообщений: 79
Есть старая программа на Delphi 2009. В программе формируется строка типа AnsiString и записывается в файл. Возникла задача вставлять внутрь этой строки также данные в Юникоде. Хорошо, делаю так:
var WStr : WideString;
   AStr : AnsiString;
   I : Integer;

for i := 1 to Length(WStr) do
   AStr := AStr + AnsiChar(Lo(Word(WStr[i]))) + AnsiChar(Hi(Word(WStr[i])));

Теперь возникла задача еще добавить два символа (BOM-заголовок) к этой строке.
AStr := #255 + #254 + AStr;

Проверил: работает, данные записываются в файл, в двоичном редакторе эти два символа отображаются как $FF и $FE.

Затем выполняю сборку программы, то есть в настройках проекта выбираю "Release" для "Build Configuration" и выполняю команду "Build" (Shift+F9) вместо "Compile". О, чудо! Теперь эти два символа записываются в файл как $79 и $3F (это коды символов "y" и "?").

То есть, символ #255 превратился в символ из таблицы Юникод с кодом 255, символ #254 - в символ с кодом 254. Затем, при вставке в AnsiString из-за русских региональных установок эти символы WideChar превратились в символы "y" и "?".

Я изменил код на этот:
AStr := AnsiChar(Byte(255)) + AnsiChar(Byte(254)) + AStr;

Был цейтнот, так что не было времени разбираться, в чем дело. Но теперь мне интересно: почему, когда "Build Configuration" был "Base", программа обрабатывала символы в кодировке ANSI одним образом, а для "Release" - другим способом? Что изменилось? Почему в одном случае программа обрабатывает эти символы как AnsiChar, в другом - как WideChar (и как это связано с вариантом компиляции программы, вот что непонятно)?

И другой вопрос: как правильно добавить два байта со значениями 255 и 254 ($FF $FE, BOM-загловок) в строку типа AnsiString? Использовать тип RawByteString? Явно указать, что это AnsiChar?
13 мар 20, 17:32    [22098733]     Ответить | Цитировать Сообщить модератору
 Re: Как прибавить BOM-заголовок к строке AnsiString?  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11602
crossa
В программе формируется строка типа AnsiString и записывается в файл
Почему бы сразу не использовать TStream?
crossa
почему, когда "Build Configuration" был "Base", программа обрабатывала символы в кодировке ANSI одним образом, а для "Release" - другим способом? Что изменилось?
Настройки проекта
crossa
Использовать тип RawByteString?
Да. Еще лучше TBytes

К сообщению приложен файл. Размер - 24Kb
13 мар 20, 17:46    [22098746]     Ответить | Цитировать Сообщить модератору
 Re: Как прибавить BOM-заголовок к строке AnsiString?  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 4217
crossa,

http://docwiki.embarcadero.com/RADStudio/Rio/en/HIGHCHARUNICODE_directive_(Delphi)

И обязательно посмотреть See Also.
13 мар 20, 17:48    [22098747]     Ответить | Цитировать Сообщить модератору
 Re: Как прибавить BOM-заголовок к строке AnsiString?  [new]
crossa
Member

Откуда:
Сообщений: 79
Да, дело явно в HIGHCHARUNICODE: один из модулей проекта содержит директиву {$HIGHCHARUNICODE ON}. Поэтому символ #255 обрабатывается как WideChar. Спасибо за помощь.

Проект старый, над ним работали разные программисты. Изначально в заголовок файла записывался текст в кодировке ANSI, поэтому используется тип AnsiString. Сейчас появилась необходимость записывать текст в Юникод, поэтому разумнее применить другой тип для переменной. Спасибо за совет использовать TBytes.
13 мар 20, 22:51    [22098912]     Ответить | Цитировать Сообщить модератору
 Re: Как прибавить BOM-заголовок к строке AnsiString?  [new]
Василий 2
Member

Откуда:
Сообщений: 1016
Явное приведение к AnsiChar - наглядно и надежно
16 мар 20, 10:38    [22099673]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить