Новейшие версии компилятора Delphi и совместимость со строковым типом - PullRequest
1 голос
/ 21 апреля 2011

Я пытаюсь сделать некоторые подпрограммы обработки строк совместимыми с новейшая версия Delphi. Я использую Delphi2005 и 2007, но я не совсем уверен в совместимости.

Вот несколько примеров, совместимы ли они со старым и новым типом строки? (Я буду использовать воображаемую директиву STRING_UNICODE).

  1. a Определение типа:

    {$IFNDEF UNICODE_STRING}  
    TextBuffer = Array[0..13] Of Char;   
    {$ELSE}  
    TextBuffer = Array[0..13] Of WideChar;  
    {$ENDIF}
    

    Бесполезно или нет? Является ли тип Char (становится тем, что был) WideChar перед строкой Unicode, или все же есть разница?

  2. Функция:

    Function RemoveBlanks(Text: String): String;  
    Var   
      i: integer;  
    Begin  
      result := '';  
      For i:= 0 To Length(Text) Do  
      Begin  
        {$IFNDEF UNICODE_STRING}   
        If Byte(Text[i]) < 21 Then Continue;   
        {$ELSE}  
        If Word(Text[i]) < 21 Then Continue;  
        {$ENDIF}  
        If Text[i] = ' ' Then Continue;    
        Result := Result + Text[i];  
      End;
    

    Оформляет ли Word () все в порядке?

    Здесь также есть проблема ' '. Как обрабатывается пространство в версии Unicode? Должен ли я также использовать директиву различать ' ' и ' ', или ' ' будет обрабатываться автоматически как 2-байтовый пробел?

  3. скачок строки:

    NewLineBegin := CanReadText( aPTextBuffer, #13#10 );
    

    Как интерпретируется второй аргумент (#13#10) в версии Unicode? Это совместимо? Будет ли он переведен в байтовый блок 00130010? Если нет, то вместо этого следует использовать директиву с константой #0013#0010?

Ответы [ 3 ]

7 голосов
/ 21 апреля 2011

Первое, что нужно сделать, это прочитать статью Марко Канту на Юникод: http://edn.embarcadero.com/article/38980

Вопрос 1

Просто используйте Char все время без условного кода, и он будет работать как в старом, так и в новом.

Char - это специальный тип, который является 8-битным типом в старых версиях Delphi и 16-битным типом в новых версиях Unicode.

Вопрос 2

Char - это порядковый тип, поэтому вы можете написать if s[i]<#21.

Вам также нужно начинать циклы с 1 для строк, так как они используют индексирование на основе 1.

Вопрос 3

Запись # 0013 не нужна, # 13 в порядке.

Короче говоря, почти весь хорошо написанный код не нуждается в изменениях.

1 голос
/ 21 апреля 2011

Универсальный тип Char становится либо фундаментальным типом AnsiChar, либо фундаментальным типом WideChar (чтение об универсальных и фундаментальных типах). Кстати, для вас уже есть UNICODE-символ $ DEFINEd, однако нет необходимости вообще разветвляться, пока не потребуется конкретный размер байта .

Вторая часть пахнет, поцарапайте ее полностью. Это злоупотребление типами и создает потребность в условной компиляции искусственно. Чтобы получить целое число без знака код символа данного Char, используйте вместо этого функцию Ord() (или, как сказано в другом ответе - используйте порядковый номер черты типа Char).

В третьей части символьные константы уже имеют общий тип Char. Опять же, не нужно беспокоиться о том, что #13 становится либо размером в байт $0D, либо размером слова $0D00 (помните о небольшом порядке байтов)

1 голос
/ 21 апреля 2011

Директивы компилятора

В общем, я бы посоветовал вам очень опасаться директив компилятора.Они служат своей цели, но для общего использования их, вероятно, следует вообще избегать.

Первая проблема заключается в том, что вам необходимо скомпилировать приложение и дважды протестировать его, поскольку оно принципиально и / или слегка отличается длядиректива вкл / выкл.

Эта ситуация ухудшается для каждой дополнительной директивы, потому что вам обычно приходится переставлять комбинации:

D1 вкл., D2 вкл.
D1 вкл., D2 выкл.
D1 выкл., D2 вкл.
D1 выкл., D2 выкл.

3 директивы - это 8 перестановок ... и т. Д.

Unicode-строки

Пожалуйста, смотрите: Готовитесь к Delphi 2009 и более поздним версиям при разработке с Delphi 7?
У него есть несколько хороших ответов для вас.

Вопрос 1

Как уже было сказано, я советую против этого,Я также советую против по другим причинам в моем ответе на вышеупомянутый вопрос.

Более конкретно:

  • В Delphi <2009 обе строки отличаются. </li>
  • В Delphi> = 2009 обе строки фактически одинаковы.

Вопрос 2

Мало того, что это плохо рекомендовано по тем же причинам, что и вопрос 1, но на самом деле есть некоторые тонкие проблемы.

Более точный тип Text (String) определяется вашей версией Delphi.Итак:

  • В Delphi <2009, остальная часть вашего условного выражения преобразует в Word один символ.(Вероятно, без вредного воздействия.) </li>
  • В Delph> = 2009, часть if вашего условия приводит двухбайтовый символ к байту.(С потерей информации.)

Также есть некоторые особые соображения и новые классы поддержки для «специальных» символов.Вы захотите посмотреть на них.См. Как определить клавиши Unicode при нажатии клавиши?

Вопрос 3

Я почти уверен, что # 13 будет рассматриваться как один символ, поэтому в Delphi> = 2009, где Char == WideChar, этот символ займет 2 байта.

Однако снова ищите Linebreakконстанты в Delphi.System.sLinebreak, вероятно, был представлен еще во времена Киликса.

...