LowerCase — Функция Delphi


Содержание

Delphi

Наши проекты

Используем функцию из SysUtils.pas:

Единственный минус этой функции это то, что она не переводит в нижний регистр русские символы

function LowCase(ch: CHAR): CHAR;
begin
case ch of
‘A’..’Z’: LowCase := CHR(ORD(ch) + 32);
‘А’..’Я’: LowCase := CHR(ORD(ch) + 32);
else
LowCase := ch;
end;
end;

Copyright © 2008 — 2020 Программирование на Delphi для начинающих и не только.

Полнота авторских прав на все материалы, опубликованные на сервере DelphiDevelop.ru принадлежит их авторам.

Перепечатка материалов разрешается с указанием авторства и гиперссылки на первоисточник информации.

LowerCase — Функция Delphi

Строки в Delphi состоят из одоного (тип ShortString ) или двух байтов (тип AnsiString, WideString ), содержащих указание количества символов в строке, и последовательности символов. Таким образом ShortString максимально может содержать до 255 символов и занимать память 2 байта ..256 байт, а AnsiString или WideString — максимально могут содержать примерно 2 x 10 30 символов и занимать память 4 байта .. 2 Гбайта.

В типе AnsiString символы кодируются в коде ANSI, а в типе WideString — в коде Unicode.

Общим типом является тип String , который может соответствовать как типу ShortString , так и типу AnsiString . Это определяется директивой компилятора $H . По умолчанию используется <$H+>, и тип String равен типу AnsiString .

Кроме того имеется тип PChar , представляющий так называемую строку с завершающим нулем. Строки с завершающим нулем не содержат байтов длины. В отличие от обычных строк они состоят из последовательности ненулевых символов, за которым следует символ NULL (#0). Никаких ограничений на длину строк с завершающим нулем не накладывается. Фактически он указывает на символ

Расширенный синтаксис позволяет ставить в соответствие строкам с завершающим нулем символьный массив типа

где X — положительное число типа Integer , определяющее количество символов в строке, не считая завершающего символа с кодом 0. В отличие от типа String , символ с индексом 0 здесь является первым символом строки, а последний символ с индексом X — завершающим символом с кодом 0. (см. Функции работы со строками с завершающим нулем)

Список литературы:

  1. Гофман В.Э., Хомоненко А.Д. Delphi 6. — СПб. БХВ-Петербург, 2002. — 1152 с.: ил.
  2. Турбо Паскаль 7.0 — К. Торгово-издательское бюро BHV, 1996 — 448 с.: ил.
  3. Delphi7 Help

How to detect if a character from a string is upper or lower case?

I’m expanding a class of mine for storing generic size strings to allow more flexible values for user input. For example, my prior version of this class was strict and allowed only the format of 2×3 or 9×12 . But now I’m making it so it can support values such as 2 x 3 or 9 X 12 and automatically maintain the original user’s formatting if the values get changed.

The real question I’m trying to figure out is just how to detect if one character from a string is either upper or lower case? Because I have to detect case sensitivity. If the deliminator is ‘x’ (lowercase) and the user inputs ‘X’ (uppercase) inside the value, and case sensitivity is turned off, I need to be able to find the opposite-case as well.

I mean, the Pos() function is case sensitive.

5 Answers 5

Delphi 7 has UpperCase() and LowerCase() functions for strings. There’s also UpCase() for characters.

If I want to search for a substring within another string case insensitively, I do this:

You simply use lower case string literals (or constants) and apply the lowercase function on the string before the search. If you’ll be doing a lot of searches, it makes sense to convert just once into a temp variable.

Here’s your case:

To see if a character is upper or lower, simply compare it against the UpCase version of it:

Работа со строками в Delphi 10.1 Berlin

Автор: Alex. Опубликовано в Программирование 31 Январь 2020 . просмотров: 23139

Для работы со строками в последних версиях Delphi разработчикам доступно большое количество функций, помимо которых ещё есть помощники для работы со строками, такие как TStringHelper, TStringBuilder и TRegEx. Во всём этом разнообразии бывает сложно найти нужную функцию. Я попытался разобраться, что есть в Delphi 10.1 Berlin для работы со строками и как этим всем пользоваться.

Итак, прежде чем начнём разбираться с функциями, замечу, что начиная с Delphi XE3, появился помощник TStringHelper, и теперь работать со строками можно как с записями. Т.е., если вы определили переменную со строкой (на картинке снизу – это myStr), то вы можете поставить точку и посмотреть, какие функции доступны. Это очень удобно.

Кстати аналогичные помощники появились и для работы с типами Single, Double и Extended: TSingleHelper, TDoubleHelper и TExtendedHelper.

Ну и конечно, помимо помощника TStringHelper, никуда не делся класс TStringBuilder, который используется для работы со строкой как с массивом, и который является полностью совместимым с .NET классом StringBuilder.

А для работы с текстовыми документами незаменимым окажется класс TRegEx, который является обёрткой над библиотекой PCRE, позволяющий использовать регулярные выражения для поиска, замены подстрок и расщепления текста на части.

Все приведённые в статье примеры сделаны с помощью Delphi 10.1 Berlin, поэтому в других версиях Delphi их работа не гарантируется.

Вот основные моменты, которые мы рассмотрим в статье:

Строки в Delphi

В последних версиях Delphi тип string, обозначающий строку, является псевдонимом встроенного типа System.UnicodeString. Т.е. когда вы объявляете переменную str: string, то автоматически вы объявляете переменную типа UnicodeString.

Кстати, на платформе Win32 вы можете использовать директиву « », которая превратит тип string в ShortString. С помощью этого способа вы можете использовать старый 16-битный код Delphi или Turbo Pascal в ваших проектах.

Обратите внимание, что кроме типа UnicodeString и ShortString в Delphi есть и другие типы строк, такие как AnsiString и WideString, однако дальше в статье мы будем рассматривать только работу со строками типа string.

Более глубокое изучение строк в Delphi вы можете начать с прочтения документации здесь.

Инициализация строк

Конечно, начнём мы с инициализации строк. Итак, рассмотрим объявление переменной с типом string.

В этой строчке кода мы объявляем переменную s с типом string, т.е., как было написано выше, по умолчанию с типом UnicodeString. Объявленные переменные с типом UnicodeString, в которые не присвоено значение, всегда гарантированно содержат строку нулевой длины. Чтобы теперь в переменной s была нужная нам строка, нужно просто присвоить переменной другое значение, например:

Это самый простой и часто используемый способ инициализации. Кроме этого есть ряд полезных функций, которые пригодятся вам для инициализации строк в некоторых ситуациях (здесь и далее я буду давать полный код проекта консольного Win32 приложения):

Изменение регистра

Для изменения регистра строк в Delphi есть функции LowerCase, UpperCase, TStringHelper.ToLower, TStringHelper.ToUpper, TStringHelper.ToLowerInvariant и TStringHelper.ToUpperInvariant. В нижний регистр строки меняют функции LowerCase, TStringHelper.ToLower и TStringHelper.ToLowerInvariant, остальные – в верхний. Обратите внимание, что функции LowerCase и UpperCase не работают с кириллицей. Функции TStringHelper.ToUpperInvariant и TStringHelper.ToLowerInvariant всегда работают независимо от текущей пользовательской локали. Вот примеры использования функций:

Конкатенация строк

Здесь конечно самый простой вариант – это использование оператора +. Но есть и другие варианты, например, функция Concat. А если вам нужно в цикле добавлять в конец одной строки большое количество других строк, то здесь пригодится метод Append класса TStringBuilder. Вот пример использования перечисленных способов:

Во всех четырёх переменных, после выполнения нашей программы, будет следующая строка: «Абвгдеёжзиклмнопрст». Четвёртый способ выглядит более громоздким, но у такого способа есть три преимущества. Во-первых, при большом количестве конкатенаций этот способ даст выигрыш по времени по сравнению с первыми тремя способами. Во-вторых, при создании объекта TStringBuilder вы сразу можете задать нужный размер массива для хранения строки, если он конечно известен. Это тоже даст выигрыш по времени. В-третьих, функция Append принимает на вход не только строки, но и другие типы, такие как Integer и Single, автоматически преобразуя их в строку.

Третий способ удобно использовать, если нужно сложить строки, находящиеся в массиве или списке. К тому же здесь первым параметром можно задать строку-разделитель, которая будет вставлена между строками, взятыми из массива. Вот пример, в котором формируется строка со списком городов, разделённых запятыми:

В результате выполнения этой функции получится строка «Москва, Санкт-Петербург, Севастополь».

Вставка подстроки в строку

Для того чтобы вставить внутрь строки подстроку вы можете использовать процедуру Insert или функцию TStringHelper.Insert. У класса TStringBuilder тоже есть аналогичная функция. Кстати, функция TStringBuilder.Insert, кроме строк умеет вставлять и другие типы, такие как Integer и Single, автоматически преобразуя их в строку. Вот пример использования:

Обратите внимание, в процедуре Insert нумерация символов начинается с 1, а в функциях TStringHelper.Insert и TStringBuilder.Insert – с 0. Все приведённые способы меняют строку, хранящуюся в переменной.

Удаление части строки

Допустим, вам нужно удалить из строки часть символов. Здесь нам помогут процедура Delete и функция TStringHelper.Remove. У класса TStringBuilder тоже есть функция Remove. Вот примеры использования:

Во всех трёх способах из строки «Абвгд» получится строка «Агд». Обратите внимание, что в процедуре Delete нумерация символов начинается с 1, а в функциях Remove – с 0.

Также интересно, что функция TStringHelper.Remove не трогает исходную строку. Вместо этого она возвращает новую строку с удалёнными символами. Именно поэтому мы присваиваем результат обратно в переменную. Процедура Delete работает по-другому: она меняет исходную строку.

Помимо приведённых здесь вариантов, для удаления части строки можно использовать функции замены подстроки, просто для этого искомая подстрока заменяется на пустую, например, StringReplace(str1, substr1, »).

Копирование части строки

Здесь идёт речь о том, что часть длиной строки нужно скопировать в новую строку или массив символов. Для этого в Delphi есть функции LeftStr, RightStr, Copy, TStringHelper.Substring и TStringHelper.CopyTo. А в классе TStringBuilder – только функция CopyTo. Есть также функция MidStr в юните System.StrUtils, которая работает аналогично функции Copy, поэтому в примере её не будет.

Первые два способа копируют часть строки слева (функция LeftStr) или справа (RightStr). Остальные четыре способа подходят, как для копирования части строки слева или справа, так и из середины.

В способах 3-6 из примера мы получим сроку «вгд» или массив [‘в’, ‘г’, ‘д’]. Обратите внимание, что в функциях Copy и MidStr нумерация символов начинается с 1, а во всех остальных с 0. Исходная строка или массив символов во всех четырёх способах не меняется.

Сравнение строк

Конечно, сравнивать строки можно с помощью операторов =, , >= и <>. Но кроме этого существуют ещё много функций: StrComp, StrIComp, StrLComp, StrLIComp, CompareStr, CompareText, TStringHelper.Compare, TStringHelper.CompareOrdinal, TStringHelper.CompareTo, TStringHelper.CompareText, SameStr, SameText, TStringHelper.Equals и TStringBuilder.Equals. Функции SameText, StrIComp, CompareText, TStringHelper.CompareText и TStringHelper.Compare умеют производить регистронезависимое сравнение строк, остальные функции и операторы — регистрозависимое.

Третьим параметром в функциях CompareText и SameText можно указать, что нужно использовать для сравнения строк пользовательскую локаль. В этом случае вы сможете сравнивать строки с русскими буквами независимо от регистра, если конечно в ОС используется русский язык.

Самая продвинутая здесь функция – это TStringHelper.Compare. С помощью неё можно сравнивать не только целые строки, но и части строк. Здесь можно настроить зависимость от регистра, включить игнорирование символов и знаков препинания или сравнение цифр как чисел и т.д.

Операторы, а также функции TStringHelper.Equals и TStringBuilder.Equals, в результате сравнения, отдадут вам True, если условие верно, и False, если условие не верно. Функции CompareStr, CompareText, TStringHelper.Compare, TStringHelper.CompareTo, TStringHelper.CompareOrdinal и TStringHelper.CompareText работают по-другому. Они сравнивают строки с точки зрения сортировки. Функции возвращают отрицательное число, если строка, указанная в первом параметре, сортируется до строки, указанной во втором параметре, положительное число — если первая строка сортируется после второй и 0 – если строки равны.

Функции SameStr, SameText, TStringHelper.Equals и TStringBuilder.Equals сравнивают строки на соответствие.

Итак, вот примеры использования вышеперечисленных функций и операторов:

Поиск подстроки в строке

Теперь давайте посмотрим, как можно найти подстроку (определённую последовательность символов) в строке. Здесь у вас есть большой выбор функций, которые возвращают либо индекс найденной подстроки, либо true или false в зависимости от того, найдена подстрока в строке или нет. Итак, давайте перечислим все функции для поиска подстроки:

В первую очередь – это функция Pos, которая ищет подстроку, начиная с указанного номера символа. Функция осуществляет регистрозависимый поиск. Здесь нумерация символов начинается с 1. Если подстрока найдена, то возвращается номер первого символа найденной подстроки, иначе – 0. Есть также функция PosEx (в юните System.StrUtils), которая работает абсолютно также. Вот пример использования функции Pos:

Аналогично функции Pos работают и функции IndexOf и LastIndexOf помощника TStringHelper. Они также осуществляют регистрозависимый поиск. Функция IndexOf ищет подстроку (или символ) с начала и до конца строки, а функция LasIndexOf – наоборот, т.е. с конца и до начала. Если подстрока найдена, то функции возвращают индекс первого символа найденной подстроки в строке. Здесь нумерация символов начинается с 0. Если подстрока не найдена, то функции возвращают -1. Также при поиске вы можете задать начало и интервал поиска. Вот примеры использования этих функций:

Теперь рассмотрим функции для проверки, есть ли подстрока в строке, и не важно, в каком месте. Для этого есть функции ContainsStr и ContainsText в юните System.StrUtils, а также функция Contains в помощнике TStringHelper.Contains. Функции ContainsStr и TStringHelper.Contains – регистрозависимые, а функция ContainsText – нет. Вот примеры использования этих функций:

Дополнительно есть функции проверяющие, наличие определённой подстроки в начале или в конце текста. Это функции StartsStr, StartsText, EndsStr и EndsText в юните System.StrUtils, а также функции StartsWith, EndsWith и EndsText у помощника TStringHelper. Функции StartsStr и EndsStr регистрозависимые, функции StartsText, EndsText и TStringHelper.EndsText регистронезависимые, а у функций TStringHelper.StartsWith и TStringHelper.EndsWith есть второй параметр для выбора режима поиска. Учтите, что регистронезависимый поиск в функции TStringHelper.StartsWith работает только с буквами латинского алфавита. По умолчанию поиск в функциях TStringHelper.StartsWith и TStringHelper.EndsWith регистрозависимый.

Обратите внимание, что регистронезависимый поиск в функциях StartsText, EndsText и TStringHelper.EndsText и TStringHelper.EndsWith ведётся для текущей локали. Т.е. если на компьютере будет установлена английская локаль, то регистронезависимый поиск по русскому тексту работать не будет.

Вот примеры использования функций:

И конечно самые продвинутые условия для поиска подстрок можно задавать при помощи регулярных выражений. Для этого есть функции TRegEx.Match и TRegEx.Matches. Вот несколько примеров использования этих функций:

Примеры и описание регулярных выражений смотрите на сайте библиотеки PCRE.

Поиск символов в строке

Случается, что нужно найти определённые символы в строке. Конечно, для этого вы можете воспользоваться функциями для поиска подстроки, о которых было написано выше, но есть и специальные функции, позволяющие найти первый попавшийся в строке символ из нескольких искомых. Это функции помощника TStringHelper: IndexOfAny, IndexOfAnyUnquoted и LastIndexOfAny. Функции IndexOfAny и IndexOfAnyUnquoted ищут, перебирая символы сначала до конца строки, а функция LastIndexOfAny – наоборот. Во всех функциях можно указать интервал поиска. Функция IndexOfAnyUnquoted умеет игнорировать символы, заключенные в кавычки, скобки и т.п. Вот пример использования этих функций:

Замена подстроки в строке

Для поиска и замены подстроки (или символа) в строке можно использовать функции StringReplace, ReplaceStr и ReplaceText, TStringHelper.Replace, TStringBuilder.Replace и TRegEx.Replace. Функции ReplaceStr и TStringBuilder.Replace – регистрозависимые, функция ReplaceText – регистронезависимая, в функциях StringReplace, TStringHelper.Replace и TRegEx.Replace зависимость от регистра настраивается флажком rfIgnoreCase. Функции TRegEx.Replace ищут подстроку, используя регулярные выражения. В функции TStringBuilder.Replace можно задать диапазон поиска подстроки. Вот примеры использования этих функций:

Обрезка пробелов и управляющих символов

Для такой часто встречающейся операции, как удаление пробелов и управляющих символов в начале и в конце строки, есть несколько функций: Trim, TrimLeft, TrimRight, TStringHelper.Trim, TStringHelper.TrimLeft и TStringHelper.TrimRight. При вызове функций TStringHelper.Trim, TStringHelper.TrimLeft и TStringHelper.TrimRight вы можете перечислить, какие символы нужно удалять. Вот пример использования этих функций:

Выравнивание текста за счёт установки пробелов

И напоследок ещё пара интересных функций, которые умеют дополнять строку пробелами или другими символами, пока она не станет нужной длины. Это функции TStringHelper.PadLeft и TStringHelper.PadRight. С помощью этих функций, например, для лучшего восприятия можно добавить пробелы в начало чисел, которые вы выдаёте столбиком в консоли или дополнить числа ведущими нулями. Вот пример использования этих функций:

Вместо заключения

Итак, в статье я постарался собрать все возможные функции Delphi, которые постоянно нужны при работе со строками. Надеюсь, вы найдёте в этой статье что-то новое и интересное для себя. Если я упустил что-то важное на ваш взгляд, просьба не держать это в себе, а написать об этом в комментариях.

LowerCase — Функция Delphi

В Delphi есть три функции для изменения регистра: upcase, lowercase, uppercase. Но они работают только для латинского алфавита. Чтобы сделать аналогичные функции для русского алфавита я использовал то, что в кодировке Windows-1251 буквы расставлены по алфавиту, как большие, так и маленькие. То есть номер большой буквы связан с номером маленькой константой. И в русском, и в английском алфавитах маленькие буквы находятся за большими с разностью в 32 символа.

Здесь реализованы четыре функции: upcase и locase для изменения регистра одного символа, и uppercase и lowercase для изменения регистра строки

DelphiComponent.ru — бесплатно видеоуроки по Delphi, статьи, исходники

Процедуры и функции для работы со строками в Delphi

Строки очень часто используются в программах — хотя бы для вывода раз­личных сообщений пользователю, чтобы он не заблудился в интерфейсе. Ну, для таких простых случаев вполне достаточно тех сведений, которые вы получили на уроке, посвящённом строкам. Если же у вас более серьёз­ные намерения и вы хотите манипулировать строками по своему желанию (например, вы пишете какую-нибудь словесную игру вроде Балды или Ло­гогрифов), то в Delphi найдётся всё нужное и для таких любителей словес­ности и жонглирования приставками и суффиксами.

Для определённости в примерах будем считать, что

Когда мы изучали простые операции со строками, то рассматривали кон­катенацию строк с помощью оператора +. Но объединить две строки можно и функцией

которая возвращает «сумму» двух строк:

Для сравнения строк вместо операторов отношения можно использовать следующие функции.

Обе функции сравнивают строки s1 и s2. Первая — с учётом регистра букв (прописные/строчные), вторая — без учёта.

Эти функции возвращают значение

0, если строки равны;

Их нельзя применять к русским словам, поэтому лучше пользоваться функциями:

которые одинаково хорошо работают и с латинскими, и с русскими буква­ми.

Теперь перейдём к процедурам и функциям, которые выполняют со сло­вами более сложные действия.

Довольно часто нужно преобразовать все буквы слова либо к верхнему, либо к нижнему регистру. Если слова состоят только из латинских букв, то можно использовать функции:

Первая переводит слова в нижний регистр (строчные буквы), вторая — в верхний (прописные буквы). Для русских ( и для латинских ) букв годятся функции :

Функция AnsiLowerCase (S1) вернёт строку «смородина».

Функция AnsiUpperCase (’смородина’) вернёт строку «СМОРОДИНА».

Процедуры вывода сообщений на экран (обычно в метку или список) тре­буют в качестве параметра строку, а что делать, если нужно предъявить пользователю число? — Преобразовать число в строку! Это можно сде­лать и самостоятельно, но гораздо удобнее воспользоваться встроенными функциями Delphi.

Чаще других в программах применяют функции для преобразования це­лых чисел в строку:

Например, IntToStr (1234) вернёт строку «1234».

Для действительных чисел тоже имеется подобная функция

Если вы хотите узнать, как десятичное число записывается в 16-ричной системе счисления, примените к нему функции:

Например, IntToHex (12 34, 8) вернёт строку «000004D2», а IntToHex (2009, 4) — строку «07D9».

Второй параметр — Digits — задаёт число цифр в 16-ричном числе.

При вводе данных из файла или некоторых компонентов вместо числа мы получаем строку символов. И хотя она состоит из цифр, это не число. В этом случае поможет функция

Причём строка S может содержать не только десятичное, но и 16-ричное число.

Например, функции StrToInt(’$07D9’) и StrToInt(’2009’) вернут одно и то же число 2009.

Однако эта функция «опасна»: если в строке обнаружится хотя бы один неверный символ, возникнет ошибка. Если у вас есть обоснованные со­мнения в правильности строки, лучше обратиться к надёжной функции

Она возвращает TRUE, если строка преобразована в число без ошибок, и FALSE, если с ошибками. Переменная Value (в нашем примере i) хранит число.

В примере строка ‘$07D9s’ содержит неверный символ «s», поэтому функ­ция вернёт FALSE и строку печатать не нужно (на самом деле значение переменной i будет равно 2009, так как функция успеет конвертировать первые символы строки — до первой «нецифры»).

Так же можно использовать и процедуру:

V — переменная целого или действительного типа.

Code — переменная целого типа, в которой возвращается номер ошибочно­го символа в строке. Если таких символов нет, то значение этой перемен­ной будет равно нулю.

В результате выполнения этого примера будет напечатано число 2009.

Этот код также напечатает число 2009, но значение переменной i будет равно не нулю, как в первом случае, а 6, так как шестой символ строки не является 16-ричной цифрой.

Аналогичные функции для вещественных чисел:

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

Первая удаляет начальные пробелы, вторая — конечные, третья — и те, и другие. Эти функции возвращают новую строку — уже без пробелов.

Узнать длину строки (число символов в ней) можно с помощью функции

Например , Length (S1) вернёт 9, а Length(S2) — 7.

Ну, а теперь — самые интересные процедуры и функции!

Удаляем часть строки S от символа номер Index:

Здесь Count — число удаляемых символов.

Например, после выполнения процедуры:

строка si будет иметь значение «РОДИНА».

А после процедуры delete(s2,5,3); строка s2 будет урезана до «ПАРА».

Если значение переменной Index меньше единицы или больше длины строки, то строка останется без изменений. Ничего не слу­чится со строкой и если Count меньше единицы.

Если же Count больше, чем число символов в строке, начиная с In­dex, то будут удалены все символы до конца строки.

Процедура Insert действует противоположно — она вставляет подстроку Substr в строку Dest после символа номер Index:

Например, после выполнения процедуры insert (’З’, s1,6); строка s1 превратится в смешное слово «СМОРОЗДИНА».

А процедура insert (’КА’, s2,8); позволит нам насладиться неологиз­неологиз­мом «ПАРАШЮТКА».

Если же мы не хотим портить исходную строку, как это делает процедура Delete, то можем создать новую строку, вырезав из любой строки нужный нам кусок:

Например, строка s примет значение «ПАРА» после выполнения функции s:=copy(s2,1,4);

Обратите внимание: чтобы получить то же самое слово, что и в примере с delete(s2,5,3);, мы указали другие значение параметров в вызове функции!

Функция copy (s1,4,9) вернёт в переменную s слово «РОДИНА».

И последняя функция находит позицию подстроки substr в строке str. function Pos(const substr: string; const str: string): Integer;

Если в строке искомая подстрока встречается несколько раз, то первый вызов функции Pos вернёт позицию первого вхождения, после чего поиск нужно продолжить со следующей позиции. Например, в слове ФЕЛЬДФЕБЕЛЬ так можно найти обе «ели».

Если же подстроки в строке нет, то вернётся безнадёжный ноль!

Программирование на языке Delphi. Глава 2. Основы языка Delphi. Часть 3

Оглавление



Программные модули


Структура модуля

Логически обособленные группы процедур и функций чрезвычайно удобно объединять в специализированные библиотеки — модули. Для этого язык Delphi предлагает специальные средства и доступную каждому технологию. Приведем общую структуру программного модуля:

После слова unit записывается имя модуля . Оно должно совпадать с именем файла, в котором находится исходный текст модуля. Например, если файл называется MathLib.pas, то модуль должен иметь имя MathLib. Заголовок модуля формируется автоматически при сохранении файла на диске, поэтому его не следует изменять вручную. Чтобы дать модулю другой заголовок, просто сохраните его на диске под другим именем.

В разделе interface описываются глобальные данные , процедуры и функции, доступные для использования в основной программе и других модулях.

В разделе implementation реализуется программный код глобальных процедур и функций и описываются локальные данные , процедуры и функции, недоступные основной программе и другим модулям.

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

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

Если модуль не нуждается в инициализации и завершении, блоки initialization и finalization можно опустить.

В качестве упражнения давайте создадим модуль и подключим его к основной программе (для этого сначала запустите среду Delphi):


    Выберите в главном меню команду File / New. , в появившемся диалоговом окне активизируйте значок с подписью Unit и щелкните на кнопке OK (рисунок 6).

Рисунок 6. Окно среды Delphi для создания нового модуля

Вы увидите, что среда Delphi создаст в редакторе кода новую страницу с текстом нового модуля Unit1 (рисунок 7):

Рисунок 7. Текст нового модуля в редакторе кода

  • Сохраните модуль под именем MathLib, выбрав в меню команду File / Save (рисунок 8):
  • Рисунок 8. Окно сохранения модуля

    Заметьте, что основная программа Console изменилась: в списке подключаемых модулей появилось имя модуля MathLib (рисунок 9). После слова in среда Delphi автоматически помещает имя файла, в котором находится модуль. Для стандартных модулей, таких как SysUtils, это не нужно, поскольку их местонахождение хорошо известно.

    Рисунок 9. Текст программы Console в окне редактора

    Теперь перейдем к содержимому модуля. Давайте объявим в нем константу Pi и две функции: Power — вычисление степени числа, и Average — вычисление среднего арифметического двух чисел:

    Вот как могла бы выглядеть программа, использующая модуль Math:

    После компиляции и запуска программы вы увидите на экране три числа (рисунок 10):

    Рисунок 10. Результат работы программы Console

    Стандартные модули языка Delphi

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

    К системным модулям относятся System, SysUtils, ShareMem, Math. В них содержатся наиболее часто используемые в программах типы данных, константы, переменные, процедуры и функции. Модуль System — это сердце среды Delphi; содержащиеся в нем подпрограммы обеспечивают работу всех остальных модулей системы. Модуль System подсоединяется автоматически к каждой программе и его не надо указывать в операторе uses .

    Модули визуальных компонентов (VCL — Visual Component Library) используются для визуальной разработки полнофункциональных GUI-приложений — приложений с графическим пользовательским интерфейсом (Graphical User Interface). Эти модули в совокупности представляют собой высокоуровневую объектно-ориентированную библиотеку со всевозможными элементами пользовательского интерфейса: кнопками, надписями, меню, панелями и т.д. Кроме того, модули этой библиотеки содержат простые и эффективные средства доступа к базам данных. Данные модули подключаются автоматически при помещении компонентов на форму, поэтому вам об этом заботиться не надо. Их список слишком велик, поэтому мы его не приводим.

    Все основные модули среды Delphi, включая модули визуальных компонентов, поставляются вместе с их исходными текстами на языке Delphi. По мере роста вашего профессионального опыта мы рекомендуем чаще обращаться к этим исходным текстам. Во-первых, в них вы найдете ответы на многие вопросы о внутреннем устройстве среды Delphi, а во-вторых, они послужат образцовым примером профессионального подхода в решении широкого круга задач. И, в-третьих, что не менее важно, это поможет научиться красиво и правильно (в рамках устоявшегося стиля) оформлять тексты Ваших собственных программ так, чтобы их с легкостью читали и понимали другие программисты.

    Исходные тексты стандартных модулей среды Delphi находятся в каталоге Delphi/Source.

    Область действия идентификаторов

    При программировании необходимо соблюдать ряд правил, регламентирующих использование идентификаторов:

    • каждый идентификатор должен быть описан перед тем, как он будет использован;
    • областью действия идентификатора является блок, в котором он описан;
    • все идентификаторы в блоке должны быть уникальными, т.е. не повторяться;
    • один и тот же идентификатор может быть по-разному определен в каждом отдельном блоке, при этом блоки могут быть вложенными;
    • если один и тот же идентификатор определен в нескольких вложенных блоках, то в пределах вложенного блока действует вложенное описание;
    • все глобальные описания подключенного модуля видны программе (подключающему модулю), как если бы они были сделаны в точке подключения;
    • если подключаются несколько модулей, в которых по-разному определен один и тот же идентификатор, то определение, сделанное в последнем подключенном модуле перекрывает все остальные;
    • если один и тот же идентификатор определен и в подключенном модуле, и в программе (подключающем модуле), то первый игнорируется, а используется идентификатор, определенный в программе (подключающем модуле). Доступ к идентификатору подключенного модуля возможен с помощью уточненного имени. Уточненное имя формируется из имени модуля и записанного через точку идентификатора. Например, чтобы в предыдущем примере получить доступ к стандартному значению числа ?, нужно записать System.Pi.

    Строки


    Строковые значения

    Строка — это последовательность символов. При программировании строковые значения заключаются в апострофы, например:

    Так как апостроф является служебным символом, для его записи в строке как значащего символа применяются два апострофа, следующих непосредственно друг за другом:

    Для записи отсутствующих на клавиатуре символов используется символ # , за которым следует десятичный номер символа в кодовой таблице ASCII, например:

    Строка, которая не содержит символов, называется пустой:

    Теперь, когда известно, что представляют собой строковые значения, займемся строковыми переменными.

    Строковые переменные

    Строковая переменная объявляется с помощью зарезервированного слова string или с помощью идентификатора типа данных AnsiString, например:

    Строку можно считать бесконечной, хотя на самом деле ее длина ограничена 2 ГБ. В зависимости от присваиваемого значения строка увеличивается и сокращается динамически. Это удобство обеспечивается тем, что физически строковая переменная хранит не сами символы, а адрес символов строки в области динамически распределяемой памяти (о динамически распределяемой памяти мы расскажем ниже). При создании строки всегда инициализируются пустым значением (»). Управление динамической памятью при операциях со строками выполняется автоматически с помощью стандартных библиотек языка Delphi.

    Вы конечно же можете описывать строковые типы данных и использовать их при объявлении переменных и типизированных констант, например:

    Символы строки индексируются от 1 до N+1, где N — реальная длина строки. Символ с индексом N+1 всегда равен нулю (#0). Для получения длины следует использовать функцию Length , а для изменения длины — процедуру SetLength (см. ниже).

    Для того чтобы в программе обратиться к отдельному символу строки, нужно сразу за идентификатором строковой переменной или константы в квадратных скобках записать его номер. Например, FriendName[1] возвращает значение ‘A’, а FriendName[4] — ‘x’. Символы, получаемые в результате индексирования строки, принадлежат типу Char.

    Достоинство строки языка Delphi состоит в том, что она объединяет в себе свойства строки самого языка Delphi и строки языка C. Оперируя строкой, вы оперируете значением строки, а не адресом в оперативной памяти. В то же время строка не ограничена по длине и может передаваться вместо C-строки (как адрес первого символа строки) в параметрах процедур и функций. Чтобы компилятор позволил это сделать, нужно, записывая строку в качестве параметра, преобразовать ее к типу PChar (тип данных, используемый в языке Delphi для описания нуль-терминированных строк языка C). Такое приведение типа допустимо по той причине, что строка всегда завершается нулевым символом (#0), который хоть и не является ее частью, тем не менее всегда дописывается сразу за последним символом строки. В результате формат строки удовлетворяет формату C-строки. О работе с нуль-терминированными строками мы поговорим чуть позже.

    Строки в формате Unicode

    Для поддержки работы со строками формата Unicode в язык Delphi имеется строковый тип данных WideString. Работа со строками типа WideString почти не отличается от работы со строками типа AnsiString; существуют лишь два отличия.

    Первое отличие состоит в представлении символов. В строках типа WideString каждый символ кодируется не одним байтом, а двумя. Соответственно элементы строки WideString — это символы типа WideChar, тогда как элементы строки AnsiString — это символы типа AnsiChar.

    Второе отличие состоит в том, что происходит при присваивании строковых переменных. Об этом вы узнаете чуть позже, прочитав параграф «Представление строк в памяти».

    Короткие строки

    Короткая строка объявляется с помощью идентификатора типа ShortString или зарезервированного слова string , за которым следует заключенное в квадратные скобки значение максимально допустимой длины, например:

    Короткая строка может иметь длину от 1 до 255 символов. Предопределенный тип данных ShortString эквивалентен объявлению string [255].

    Реальная длина строки может быть меньше или равна той, что указана при ее объявлении. Например, максимальная длина строки Friend в примере выше составляет 30 символов, а ее реальная длина — 9 символов. Реальную длину строки можно узнать с помощью встроенной функции Length . Например, значение Length(Friend) будет равно 9 (количество букв в слове Alexander).

    Все символы в строке типа ShortString пронумерованы от 0 до N, где N — максимальная длина, указанная при объявлении. Символ с номером 0 — это служебный байт, в нем содержится реальная длина короткой строки. Значащие символы нумеруются от 1. Очевидно, что в памяти строка занимает на 1 байт больше, чем ее максимальная длина. Поэтому значение SizeOf(Friend) будет равно 31.

    Обратиться к отдельному символу можно так же, как и к символу обычной строки. Например, выражения FriendName[1] и FriendName[9] возвращают соответственно символы ‘A’ и ‘r’. Значения FriendName[10] .. FriendName[30] будут случайными, так как при объявлении типизированной константы FriendName символы с номерами от 10 до 30 не были инициализированы. Символы, получаемые в результате индексирования короткой строки, принадлежат типу Char.

    Поскольку существует два типа строк: обычные (длинные) строки и короткие строки, возникает закономерный вопрос, можно ли их совмещать. Да, можно! Короткие и длинные строки могут одновременно использоваться в одном выражении, поскольку компилятор языка Delphi автоматически генерирует код, преобразующий их тип. Более того, можно выполнять явные преобразования строк с помощью конструкций вида ShortString(S) и AnsiString(S).

    Операции над строками

    Выражения, в которых операндами служат строковые данные, называются строковыми . Они состоят из строковых констант, переменных, имен функций и строковых операций. Над строковыми данными допустимы операции сцепления и отношения.

    Операция сцепления (+) применяется для сцепления нескольких строк в одну строку.

    Выражение


    Результат


    ‘Object’ + ‘ Pascal’ ‘Object Pascal’

    Операции отношения (=, <>, >, =, ‘ABCDE’ True ‘Office’ = ‘Office’ True ‘USIS’ > ‘US’ True

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

    Объявление строки


    Выражение


    Значение строки


    Name: string[6]; Name := ‘Mark Twain’; ‘Mark T’

    Допускается смешение в одном выражении операндов строкового и символьного типа, например при сцеплении строки и символа.

    Строковые ресурсы

    В языке Delphi существует специальный вид строковых данных — строковые ресурсы. Строковые ресурсы очень похожи на строковые константы, но отличаются от них тем, что размещаются не в области данных программы, а в специальной области выполняемого файла, называемой ресурсами. Если данные всегда загружаются вместе с кодом программы и остаются в оперативной памяти вплоть до завершения программы, то ресурсы подгружаются в оперативную память лишь по мере надобности.

    В программе строковые ресурсы описываются как обычные строковые константы, с той лишь разницей что раздел их описания начинается не словом const , а словом resourcestring :

    Использование строковых ресурсов ничем не отличается от использования строковых констант:

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

    Форматы кодирования символов

    Существуют различные форматы кодирования символов. Отдельный символ строки может быть представлен в памяти одним байтом (стандарт Ansi), двумя байтам (стандарт Unicode) и даже четырьмя байтами (стандарт UCS-4 — Unicode). Строка «Wirth» (фамилия автора языка Pascal — прародителя языка Delphi) будет представлена в указанных форматах следующим образом (рисунок 11):

    Рисунок 11. Форматы кодирования символов

    Существует также формат кодирования MBCS (Multibyte Character Set), согласно которому символы одной строки кодируются разным количеством байт (одним или двумя байтами в зависимости от алфавита). Например, буквы латинского алфавита кодируются одним байтом, а иероглифы японского алфавита — двумя. При этом латинские буквы и японские иероглифы могут встречаться в одной и той же строке.

    Стандартные процедуры и функции для работы со строками

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

    • Concat (S1, S2, . , Sn): string — возвращает строку, полученную в результате сцепления строк S1, S2, . Sn. По своей работе функция Concat аналогична операции сцепления (+).
    • Copy (S: string, Index, Count: Integer): string — выделяет из строки S подстроку длиной Count символов, начиная с позиции Index.
    • Delete (var S: string, Index, Count: Integer) — удаляет Count символов из строки S, начиная с позиции Index.
    • Insert (Source: string; var S: string, Index: Integer) — вставляет строку Source в строку S, начиная с позиции Index.
    • Length (S: string): Integer — возвращает реальную длину строки S в символах.
    • SetLength (var S: string; NewLength: Integer) — устанавливает для строки S новую длину NewLength.

    Выражение


    Значение S


    S := Concat(‘Object ‘, ‘Pascal’);‘Object Pascal’S:= Copy(‘Debugger’, 3, 3);‘bug’S := ‘Compile’; Delete(S, 1, 3);‘pile’S := ‘Faction’; Insert(‘r’, S, 2)‘Fraction’

    • Pos (Substr, S: string): Byte — обнаруживает первое появление подстроки Substr в строке S. Возвращает номер той позиции, где находится первый символ подстроки Substr. Если в S подстроки Substr не найдено, результат равен 0.

    Выражение


    Результат


    Pos(‘rat’, ‘grated’)2Pos(‘sh’, ‘champagne’)

    • Str (X [: Width [: Decimals] ], var S: string) — преобразует числовое значение величины X в строку S. Необязательные параметры Width и Decimals являются целочисленными выражениями. Значение Width задает ширину поля результирующей строки. Значение Decimals используется с вещественными числами и задает количество символов в дробной части.

    Выражение


    Значение S


    Str(-200, S);‘-200’Str(200 : 4, S);‘ 200’Str(1.5E+02 : 4, S);‘ 150’

    • Val (S: string, var V; var Code: Integer) — преобразует строку S в величину целого или вещественного типа и помещает результат в переменную V. Если во время операции преобразования ошибки не обнаружено, значение переменной Code равно нулю; если ошибка обнаружена (строка содержит недопустимые символы), Code содержит номер позиции первого ошибочного символа, а значение V не определено.

    Выражение


    Значение V


    Значение Code


    Val(‘100’, V, Code); 100 Val(‘2.5E+01’, V, Code); 25.0 Val(‘2.5A+01’, V, Code); 4

    Описанные процедуры и функции являются базовыми для всех остальных подпрограмм обработки строк из модуля SysUtils.

    • AdjustLineBreaks (const S: string): string — возвращает копию строки S, в которой все мягкие переносы строк (одиночные символы #13 или #10) заменены жесткими переносами строк (последовательность символов #13#10).
    • AnsiCompareStr (const S1, S2: string): Integer — сравнивает две строки, делая различие между заглавными и строчными буквами; учитывает местный язык. Возвращаемое значение меньше нуля, если S1 S2.
    • AnsiCompareText (const S1, S2: string): Integer — сравнивает две строки, не делая различий между заглавными и строчными буквами; учитывает местный язык. Возвращаемое значение меньше нуля, если S1 S2.
    • AnsiDequotedStr (const S: string; Quote: Char): string — удаляет специальный символ, заданный параметром Quote, из начала и конца строки и заменяет парные спецсимволы на одиночные; если специальный символ отсутствует в начале или конце строки, то функция возвращает исходную строку без изменений.
    • AnsiExtractQuotedStr (var Src: PChar; Quote: Char): string — делает то же, что и функция AnsiDequotedStr, но результат возвращается вместо исходной строки, которая имеет тип PChar.
    • AnsiLowerCase (const S: string): string — преобразует заглавные буквы строки S к строчным буквам с учетом местного языка.
    • AnsiPos (const Substr, S: string): Integer — выполняет те же действия, что и функция Pos, но в отличие от нее поддерживает работу с многобайтовой MBCS-кодировкой.
    • AnsiQuotedStr (const S: string; Quote: Char): string — преобразует строку, заменяя все вхождения специального символа, заданного параметром Quote, на парные спецсимволы, а также помещает специальный символ в начало и конец строки. Поддерживает работу с MBCS-кодировкой.
    • AnsiSameCaption (const Text1, Text2: string): Boolean — сравнивает две строки, не делая различие между заглавными и строчными буквами, а также не учитывая символ ‘&’; учитывает местный язык.
    • AnsiSameStr (const S1, S2: string): Boolean — сравнивает строки, делая различие между строчными и заглавными буквами; учитывает местный язык.
    • AnsiSameText (const S1, S2: string): Boolean — сравнивает строки, не делая различие между строчными и заглавными буквами; учитывает местный язык.
    • AnsiUpperCase (const S: string): string — преобразует все строчные буквы в заглавные; учитывает местный язык.
    • CompareStr (const S1, S2: string): Integer — выполняет сравнение двух строк, делая различие между строчными и заглавными буквами; не учитывает местный язык. Возвращаемое значение меньше нуля, если S1 S2.
    • CompareText (const S1, S2: string): Integer — выполняет сравнение двух строк, не делая различий между строчными и заглавными буквами; не учитывает местный язык. Возвращаемое значение меньше нуля, если S1 S2.
    • DateTimeToStr (const DateTime: TDateTime): string — преобразует значение даты и времени в строку.
    • DateTimeToString (var Result: string; const Format: string; DateTime: TDateTime) — преобразует значение даты и времени в строку, выполняя при этом форматирование в соответствии со значением строки Format. Управляющие символы строки Format подробно описаны в справочнике по среде Delphi.
    • DateToStr (const DateTime: TDateTime): string — преобразует числовое значение даты в строку.
    • Format (const Format: string; const Args: array of const): string — форматирует строку в соответствии с шаблоном Format, заменяя управляющие символы шаблона на значения элементов открытого массива Args. Управляющие символы подробно описаны в справочнике по среде Delphi.
    • FormatDateTime (const Format: string; DateTime: TDateTime): string — преобразует значение даты и времени в строку, выполняя при этом форматирование в соответствии со значением строки Format. Управляющие символы строки Format подробно описаны в справочнике по среде Delphi.
    • BoolToStr (B: Boolean; UseBoolStrs: Boolean = False): string — преобразует булевское значение в строку. Если параметр UseBoolStrs имеет значение False, то результатом работы функции является одно из значений ‘0’ или ‘-1’. Если же параметр UseBoolStrs имеет значение True, то результатом работы является одно из значений ‘FALSE’ или ‘TRUE’ (программист может задать другие значения; о том, как это сделать, читайте в справочнике по системе Delphi).
    • IntToHex (Value: Integer; Digits: Integer): string — возвращает шестнадцатиричное представление целого числа Value. Параметр Digits задает количество цифр результирующей строки.
    • IntToStr (Value: Integer): string — преобразует целое число Value в строку.
    • IsDelimiter (const Delimiters, S: string; Index: Integer): Boolean — проверяет, является ли символ S[Index] одним из символов строки Delimiters. Функция поддерживает работу с многобайтовой MBCS-кодировкой.
    • IsValidIdent (const Ident: string): Boolean — возвращает True, если строка Ident является правильным идентификатором языка Delphi.
    • LastDelimiter (const Delimiters, S: string): Integer — возвращает индекс последнего вхождения одного из символов строки Delimiters в строку S.
    • LowerCase (const S: string): string — преобразует все заглавные буквы строки S к строчным; не учитывает местный язык (в преобразовании участвуют лишь символы в диапазоне от ‘A’ до ‘Z’).
    • QuotedStr (const S: string): string — преобразует исходную строку в строку, взятую в одиночные кавычки; внутри строки символы кавычки дублируются.
    • SameText (const S1, S2: string): Boolean — сравнивает строки, не делая различие между строчными и заглавными буквами; учитывает местный язык.
    • SetString (var S: string; Buffer: PChar; Len: Integer) — копирует строку с типом PChar в строку с типом string. Длина копируемой строки задается параметром Len.
    • StringOfChar (Ch: Char; Count: Integer): string — возвращает строку, в которой повторяется один и тот же символ. Количество повторений задается параметром Count.
    • StringToGUID (const S: string): TGUID — преобразует строковое представление глобального уникального идентификатора в стандартный тип TGUID.
    • StrToBool (const S: string): Boolean — преобразует строку в булевское значение.
    • StrToBoolDef (const S: string; const Default: Boolean): Boolean — преобразует строку в булевское значение. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.
    • StrToDate (const S: string): TDateTime — преобразует строку со значением даты в числовой формат даты и времени.
    • StrToDateDef (const S: string; const Default: TDateTime): TDateTime — преобразует строку со значением даты в числовой формат даты и времени. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.
    • StrToDateTime (const S: string): TDateTime — преобразует строку в числовое значение даты и времени.
    • StrToDateTimeDef (const S: string; const Default: TDateTime): TDateTime — преобразует строку в числовое значение даты и времени. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.
    • StrToInt (const S: string): Integer — преобразует строку в целое число. Если строка не может быть преобразована в целое число, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).
    • StrToIntDef (const S: string; Default: Integer): Integer — преобразует строку в целое число. Если строка не может быть преобразована в целое число, функция возвращает значение, заданное параметром Default.
    • StrToInt64 (const S: string): Int64 — 64-битный аналог функции StrToInt — преобразует строку в 64-битное целое число. Если строка не может быть преобразована в 64-битное число, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).
    • StrToInt64Def (const S: string; const Default: Int64): Int64 — 64-битный аналог функции StrToIntDef — преобразует строку в 64-битное целое число. Если строка не может быть преобразована в 64-битное число, функция возвращает значение, заданное параметром Default.
    • StrToTime (const S: string): TDateTime — преобразует строку в числовой формат времени. Если строка не может быть преобразована в числовой формат времени, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).
    • StrToTimeDef (const S: string; const Default: TDateTime): TDateTime — преобразует строку в числовой формат времени. В случае ошибки преобразования, функция возвращает значение, заданное параметром Default.
    • TimeToStr (Time: TDateTime): string — преобразует числовое значение времени в строку.
    • Trim (const S: string): string — возвращает часть строки S без лидирующих и завершающих пробелов и управляющих символов.
    • Trim (const S: WideString): WideString — Unicode-аналог функции Trim — возвращает часть строки S без лидирующих и завершающих пробелов и управляющих символов.
    • TrimLeft (const S: string): string — возвращает часть строки S без лидирующих пробелов и управляющих символов.
    • TrimLeft const S: WideString): WideString — Unicode-аналог функции TrimLeft — возвращает часть строки S без лидирующих пробелов и управляющих символов.
    • TrimRight (const S: string): string — возвращает часть строки S без завершающих пробелов и управляющих символов.
    • TrimRight (const S: WideString): WideString — Unicode-аналог функции TrimRight — возвращает часть строки S без завершающих пробелов и управляющих символов.
    • UpperCase (const S: string): string — преобразует все строчные буквы строки S в заглавные; не учитывает местный язык (в преобразовании участвуют лишь символы в диапазоне от ‘a’ до ‘z’).
    • WideFormat (const Format: WideString; const Args: array of const): WideString — Unicode-аналог функции Format, учитывающий символы местного языка, — форматирует строку в соответствии с шаблоном Format, заменяя управляющие символы в шаблоне на значения элементов открытого массива Args. Управляющие символы подробно описаны в справочнике по системе Delphi.
    • WideFmtStr (var Result: WideString; const Format: WideString; const Args: array of const) — аналог функции WideFormat. Отличие в том, что WideFmtStr возвращает результат через параметр Result, а не как значение функции.
    • WideLowerCase const S: WideString): WideString — Unicode-аналог функции LowerCase (учитывает местный язык) — преобразует все заглавные буквы строки S к строчным буквам.
    • WideSameCaption (const Text1, Text2: WideString): Boolean — Unicode-аналог функции AnsiSameCaption — сравнивает две строки, не делая различие между строчными и заглавными буквами, а также не учитывая символ ‘&’; учитывает местный язык.
    • WideSameStr (const S1, S2: WideString): Boolean — Unicode-аналог стандартной операции сравнения строк — сравнивает две строки, делая различие между строчными и заглавными буквами.
    • WideSameText (const S1, S2: WideString): Boolean — Unicode-аналог функции SameText (учитывает местный язык) — сравнивает строки, не делая различие между строчными и заглавными буквами.
    • WideUpperCase (const S: WideString): WideString — Unicode-аналог функции UpperCase (учитывает местный язык) — преобразует все строчные буквы строки S в заглавные.
    • WrapText (const Line: string; MaxCol: Integer = 45): string — разбивает текст Line на строки, вставляя символы переноса строки. Максимальная длина отдельной строки задается параметром MaxCol.
    • WrapText (const Line, BreakStr: string; const BreakChars: TSysCharSet; MaxCol: Integer): string — более мощный аналог предыдущей функции — разбивает текст Line на строки, вставляя символы переноса строки.
    • AnsiToUtf8 (const S: string): UTF8String — перекодирует строку в формат UTF8.
    • PUCS4Chars (const S: UCS4String): PUCS4Char — возвращает указатель на первый символ строки формата UCS-4 для работы со строкой, как с последовательностью символов, заканчивающейся символом с кодом нуль.
    • StringToWideChar (const Source: string; Dest: PWideChar; DestSize: Integer): PWideChar — преобразует стандартную строку к последовательности Unicode-символов, завершающейся символом с кодом нуль.
    • UCS4StringToWideString (const S: UCS4String): WideString — преобразует строку формата UCS-4 к строке формата Unicode.
    • Utf8Decode (const S: UTF8String): WideString — преобразует строку формата UTF-8 к строке формата Unicode.
    • Utf8Encode (const WS: WideString): UTF8String — преобразует строку формата Unicode к строке формата UTF-8.
    • Utf8ToAnsi (const S: UTF8String): string — преобразует строку формата UTF-8 к стандратной строке.
    • WideCharLenToString (Source: PWideChar; SourceLen: Integer): string — преобразует строку формата Unicode к стандартной строке. Длина исходной строки задается параметром SourceLen.
    • WideCharLenToStrVar (Source: PWideChar; SourceLen: Integer; var Dest: string) — аналог предыдущей функции — преобразует строку формата Unicode к стандартной строке. Длина исходной строки задается параметром SourceLen, а результат возвращается через параметр Dest.
    • WideCharToString (Source: PWideChar): string — преобразует последовательность Unicode-символов, завершающуюся символом с кодом нуль, к стандартной строке.
    • WideCharToStrVar (Source: PWideChar; var Dest: string) — аналог предыдущей функции — преобразует последовательность Unicode-символов, завершающуюся символом с кодом нуль, к стандартной строке. Результат возвращается через параметр Dest.
    • WideStringToUCS4String (const S: WideString): UCS4String — преобразует строку формата Unicode к строке формата UCS-4.

    Массивы


    Объявление массива

    Массив — это составной тип данных, состоящий из фиксированного числа элементов одного и того же типа. Для описания массива предназначено словосочетание array of . После слова array в квадратных скобках записываются границы массива, а после слова of — тип элементов массива, например:

    После описания типа можно переходить к определению переменных и типизированных констант:

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

    Массив может быть определен и без описания типа:

    Чтобы получить доступ к отдельному элементу массива, нужно в квадратных скобках указать его индекс, например

    Объявленные выше массивы являются одномерными, так как имеют только один индекс. Одномерные массивы обычно используются для представления линейной последовательности элементов. Если при описании массива задано два индекса, массив называется двумерным , если n индексов — n-мерным . Двумерные массивы используются для представления таблицы, а n-мерные — для представления пространств. Вот пример объявления таблицы, состоящей из 5 колонок и 20 строк:

    То же самое можно записать в более компактном виде:

    Чтобы получить доступ к отдельному элементу многомерного массива, нужно указать значение каждого индекса, например

    или в более компактной записи

    Эти два способа индексации эквивалентны.

    Работа с массивами

    Массивы в целом участвуют только в операциях присваивания. При этом все элементы одного массива копируются в другой. Например, если объявлены два массива A и B,

    то допустим следующий оператор:

    Оба массива-операнда в левой и правой части оператора присваивания должны быть не просто идентичны по структуре, а описаны с одним и тем же типом, иначе компилятор сообщит об ошибке. Именно поэтому все массивы рекомендуется описывать в секции type .

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

    Для массивов определены две встроенные функции — Low и High. Они получают в качестве своего аргумента имя массива. Функция Low возвращает нижнюю, а High — верхнюю границу этого массива. Например, Low(A) вернет значение 1, а High(A) — 5. Функции Low и High чаще всего используются для указания начального и конечного значений в операторе цикла for . Поэтому вычисление суммы элементов массива A лучше переписать так:

    В операциях с многомерными массивами циклы for вкладываются друг в друга. Например, для инициализации элементов таблицы, объявленной как

    требуются два вложенных цикла for и две целые переменные Col и Row для параметров этих циклов:

    Массивы в параметрах процедур и функций

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

    Функция Average принимает в качестве параметра массив известной размерности. Требование фиксированного размера для массива-параметра часто является чрезмерно сдерживающим фактором. Процедура для нахождения среднего значения должна быть способна работать с массивами произвольной длины. Для этой цели в язык Delphi введены открытые массивы-параметры. Такие массивы были заимствованы разработчиками языка Delphi из языка Modula-2. Открытый массив-параметр описывается с помощью словосочетания array of , при этом границы массива опускаются:

    Внутри подпрограммы Average нижняя граница открытого массива A равна нулю (Low(A) = 0), а вот значение верхней границы (High(A)) неизвестно и выясняется только на этапе выполнения программы.

    Существует только два способа использования открытых массивов: обращение к элементам массива и передача массива другой подпрограмме, принимающей открытый массив. Нельзя присваивать один открытый массив другому, потому что их размеры заранее неизвестны.

    Вот пример использования функции Average:

    Заметьте, что во втором операторе открытый массив конструируется в момент вызова функции Average. Конструктор открытого массива представляет собой заключенный в квадратные скобки список выражений. В выражениях могут использоваться константы, переменные и функции. Тип выражений должен быть совместим с типом элементов массива. Конструирование открытого массива равносильно созданию и инициализации временной переменной.

    И еще одно важное замечание по поводу открытых массивов. Некоторые библиотечные подпрограммы языка Delphi принимают параметры типа array of const — открытые массивы констант . Массив, передаваемый в качестве такого параметра, обязательно конструируется в момент вызова подпрограммы и может состоять из элементов различных типов (!). Физически он состоит из записей типа TVarRec , кодирующих тип и значение элементов массива (записи рассматриваются ниже). Открытый массив констант позволяет эмулировать подпрограммы с переменным количеством разнотипных параметров и используется, например, в функции Format для форматирования строки (см. выше).

    Уплотнение структурных данных в памяти

    С целью экономии памяти, занимаемой массивами и другими структурными данными, вы можете предварять описание типа зарезервированным словом packed , например:

    Ключевое слово packed указывает компилятору, что элементы структурного типа должны храниться плотно прижатыми друг к другу, даже если это замедляет к ним доступ. Если структурный тип данных описан без ключевого слова packed , компилятор выравнивает его элементы на 2- и 4-байтовых границах, чтобы ускорить к ним доступ.

    Заметим, что ключевое слово packed применимо к любому структурному типу данных, т.е. массиву, множеству, записи, файлу, классу, ссылке на класс.

    Множества


    Объявление множества

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

    Для описания множественного типа используется словосочетание set of , после которого записывается базовый тип множества:

    Теперь можно объявить переменную множественного типа:

    Можно объявить множество и без предварительного описания типа:

    В выражениях значения элементов множества указываются в квадратных скобках: [2, 3, 5, 7], [1..9], [‘A’, ‘B’, ‘C’]. Если множество не имеет элементов, оно называется пустым и обозначается как [ ]. Пример инициализации множеств:

    Количество элементов множества называется мощностью . Мощность множества в языке Delphi не может превышать 256.

    Операции над множествами

    При работе с множествами допускается использование операций отношения (=, <>, >=, in .

    Операции сравнения (=, <>). Два множества считаются равными, если они состоят из одних и тех же элементов. Порядок следования элементов в сравниваемых множествах значения не имеет. Два множества A и B считаются не равными, если они отличаются по мощности или по значению хотя бы одного элемента.

    Выражение


    Результат


    [1, 2] <> [1, 2, 3] True [1, 2] = [1, 2, 2] True [1, 2, 3] = [3, 2, 1] True [1, 2, 3] = [1..3] True

    Операции принадлежности (>=, = B равно True, если все элементы множества B содержатся в множестве A. Выражение A = [1, 2] True [1, 2] in . Используется для проверки принадлежности элемента указанному множеству. Обычно применяется в условных операторах.

    Выражение


    Результат


    5 in [1..9] True 5 in [1..4, 6..9] False

    Операция in позволяет эффективно и наглядно выполнять сложные проверки условий, заменяя иногда десятки других операций. Например, оператор

    можно заменить более коротким:

    Операцию in иногда пытаются записать с отрицанием: X not in S. Такая запись является ошибочной, так как две операции следуют подряд. Правильная запись имеет вид: not (X in S).

    Объединение множеств (+) . Объединением двух множеств является третье множество, содержащее элементы обоих множеств.


    Выражение


    Результат


    [ ] + [1, 2] [1, 2] [1, 2] + [2, 3, 4] [1, 2, 3, 4]

    Пересечение множеств (*) . Пересечение двух множеств — это третье множество, которое содержит элементы, входящие одновременно в оба множества.

    Выражение


    Результат


    [ ] * [1, 2] [ ] [1, 2] * [2, 3, 4] [2]

    Разность множеств (-) . Разностью двух множеств является третье множество, которое содержит элементы первого множества, не входящие во второе множество.

    Выражение


    Результат


    [1, 2, 3] — [2, 3] [1] [1, 2, 3] — [ ] [1, 2, 3]

    В язык Delphi введены две стандартные процедуры Include и Exclude, которые предназначены для работы с множествами.

    Процедура Include (S, I) включает в множество S элемент I. Она дублирует операцию + (плюс) с той лишь разницей, что при каждом обращении включает только один элемент и делает это более эффективно.

    Процедура Exclude (S, I) исключает из множества S элемент I. Она дублирует операцию — (минус) с той лишь разницей, что при каждом обращении исключает только один элемент и делает это более эффективно.

    Выражение


    Результат


    S := [1, 3]; [1, 3] Include(S, 2); [1, 2, 3] Exclude(S, 3) [1, 2]

    Использование в программе множеств дает ряд преимуществ: значительно упрощаются сложные операторы if , улучшается наглядность программы и понимание алгоритма решения задачи, экономится время разработки программы. Поэтому множества широко используются в библиотеке компонентов среды Delphi.

    Записи


    Объявление записи

    Запись — это составной тип данных, состоящий из фиксированного числа элементов одного или нескольких типов. Описание типа записи начинается словом record и заканчивается словом end . Между ними заключен список элементов, называемых полями , с указанием идентификаторов полей и типа каждого поля:

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

    Чтобы получить в программе реальную запись, нужно создать переменную соответствующего типа:

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

    Доступ к содержимому записи осуществляется посредством идентификаторов переменной и поля, разделенных точкой. Такая комбинация называется составным именем . Например, чтобы получить доступ к полям записи Friend, нужно записать:

    Обращение к полям записи имеет несколько громоздкий вид, что особенно неудобно при использовании мнемонических идентификаторов длиной более 5 символов. Для решения этой проблемы в языке Delphi предназначен оператор with, который имеет формат:

    Однажды указав имя записи в операторе with, можно работать с именами ее полей как с обычными переменными, т.е. без указания идентификатора записи перед идентификатором поля:

    Допускается применение оператора присваивания и к записям в целом, если они имеют один и тот же тип. Например,

    После выполнения этого оператора значения полей записи Friend станут равными значениям соответствующих полей записи BestFriend.

    Записи с вариантами

    Строго фиксированная структура записи ограничивает возможность ее применения. Поэтому в языке Delphi имеется возможность задать для записи несколько вариантов структуры. Такие записи называются записями с вариантами . Они состоят из необязательной фиксированной и вариантной частей.

    Вариантная часть напоминает условный оператор case . Между словами case и of записывается особое поле записи — поле признака . Оно определяет, какой из вариантов в данный момент будет активизирован. Поле признака должно быть равно одному из расположенных следом значений. Каждому значению сопоставляется вариант записи. Он заключается в круглые скобки и отделяется от своего значения двоеточием. Пример описания записи с вариантами:

    Обратите внимание, что у вариантной части нет отдельного end , как этого можно было бы ожидать по аналогии с оператором case . Одно слово end завершает и вариантную часть, и всю запись.

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

    Использование процедур и функций в Delphi

    Скобки

    Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.

    Возможность перегрузки

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

    procedure Test (I: integer); overload;
    procedure Test (S: string); overload;
    procedure Test (D: double); overload;

    При вызове процедуры Test, Delphi сама решит, какую из трех процедур необходимо выполнить, в зависимости от передаваемого ей параметра. Но нужно отметить, что это не самая безопасная возможность языка. Применение перегружаемых процедур и функций может стать неиссякаемым источником трудноуловимых ошибок в программе. Поэтому пользуйтесь этой возможностью осторожно.

    Передача параметров

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

    Передача параметров по значению

    Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:

    procedure Test(s: string);

    При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

    Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно). Этот способ передачи является у большинства самым излюбленным, но в тоже время является и самым не практичным, т.к. для выполнения метода выделяется дополнительная память для создания точной копией передаваемой переменой. Для решения этой проблемы следует использовать один из способов описанных ниже.

    Передача параметров по ссылке

    Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

    procedure ChangeMe(var x: longint);
    begin
    x := 2; // Параметр х изменен вызванной процедурой
    end;

    Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

    Передача параметров констант

    Если нет необходимости изменять передаваемые функции или процедуре данные, можно описать параметр как константу. Ключевое слово const не только защищает параметр от изменения, но и позволяет компилятору сгенерировать более оптимальный код передачи строк и записей. Вот пример объявления параметра-константы:

    procedure Test(const s: string );

    Передача открытых массивов

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

    function AddEmUp(A: array of integer): integer;

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

    Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

    Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

    procedure WhatHaveIGot( A: array of const );

    Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

    procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

    При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

    PVarRec = ^TVarRec;
    TVarRec = record
    case Byte of
    vtInteger: (VInteger: Integer; VType: Byte);
    vtBoolean: (VBoolean: Boolean);
    vtChar: (VChar: Char);
    vtExtended: (VExtended: PExtended);
    vtString: (VString: PShortString);
    vtPointer: (VPointer: Pointer);
    vtPChar: (VPChar: PChar);
    vtObject: (VObject: TObject);
    vtClass: (VClass: TClass);
    vtWideChar: (VWideChar: WideChar);
    vtPWideChar: (VPWideChar: PWideChar);
    vtAnsiString: (VAnsiString: Pointer);
    vtCurrency: (VCurrency: PCurrency);
    vtVariant: (VVariant: PVariant);
    vtInterface: (VInterface: Pointer);
    vtWideString: (VWideString: Pointer);
    vtInt64: (VInt64: PInt64);
    end;

    Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.

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

    procedure WhatHaveIGot( A: array of const );
    var
    i: integer;
    TypeStr: string;
    begin
    for i := Low(A) to High(A) do
    begin
    case A[i].VType of
    vtInteger : TypeStr := ‘Integer’;
    vtBoolean : TypeStr := ‘Boolean’;
    vtChar : TypeStr := ‘Char’;
    vtExtended : TypeStr := ‘Extended’;
    vtString : TypeStr := ‘String’;
    vtPointer : TypeStr := ‘Pointer’;
    vtPChar : TypeStr := ‘PChar’;
    vtObject : TypeStr := ‘Object’;
    vt ;
    vtW ;
    vtPW ;
    vtAnsiString : TypeStr := ‘AnsiString’;
    vtCurrency : TypeStr := ‘Currency’;
    vtVariant : TypeStr := ‘Variant’;
    vtInterface : TypeStr := ‘Interface’;
    vtW ;
    vtInt64 : TypeStr := ‘Int64’;
    end;
    ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
    end;
    end;

    Значения параметров по умолчанию

    В Delphi есть одна очень полезная возможность — использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:

    procedure HasDefVal( s: string; i: integer = 0 );

    Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

    procedure HasDefVal( ‘Hello’, 26 );

    Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

    procedure HasDefVal( ‘Hello’ );

    При использовании значении параметров по умолчанию следует помнить о нескольких приведенных ниже правилах:

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

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

    function Add( I1, I2: integer ): integer;
    begin
    Result := I1 + I2;
    end;

    Предположим также, что исследования показали целесообразность добавления в программу возможности сложения трех чисел. Однако замена имеющейся функции функцией сложения трех чисел приведет к тому, что вам придется переправлять немало текста, который перестанет компилироваться из-за внесения в функцию еще одного параметра. Однако при использовании значений параметров по умолчанию проблема решается легко и просто. Достаточно изменить объявление функции так, как показано ниже.

    function Add( I1, I2: integer; I3: integer = 0 ): integer;
    begin
    Result := I1 + I2 + I3;
    end;

    Директива

    Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

    В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

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

    The Programming Works

    Delphi programming and more

    How to uppecase [lowercase] strings in Delphi 2009+ ?

    The answer is not so obvious as it was before.

    In the time immemorial strings were ASCII strings, and since then we have UpperCase function. The function is just replaces the lowercase ‘a’..’z’ characters by their uppercase ‘A’..’Z’ versions. Though nowadays the UpperCase is a Unicode function it still ‘uppercases’ only ASCII characters. That is good but that is not all uppercase functionality we need.

    The early Delphi versions introduced ANSI strings. The uppercase conversion on ANSI strings includes local characters besides ASCII ‘a’..’z’ and consequntly is locale-dependent. The only locale supported by pre-unicode Delphi versions is system locale. The ANSIUpperCase function was introduced to uppercase ANSI strings using system locale. That is not so good as it may be, since sometimes we need a locale different from system locale, but at least is clear and unambiguous.

    Now in Delphi2009 we can explicitly define the ANSI locale in Ansistring type, and that is great. The ANSI uppercase conversion is locale-sensitive, and now we can perform ANSI string uppercase conversions on any locale by just calling AnsiUpperCase function, right? The answer is – NO.

    First, in Delphi 2009 the AnsiUpperCase is unicode function. I understand the [compatibility] reasons why the unicode function has Ansi prefix, but I prefer it would never happen.

    Second, the real ANSI version of AnsiUpperCase function defined in Ansistrings unit is a wrapper for WinAPI CharUpperBuffA function, and still uses the current system locale and ignores the locale associated with the string type.

    As a result it is better to avoid using AnsiUpperCase at all. The AnsiUpperCase function is just a backward compatibility issue.

    Nowadays the defaul string type is Unicode string. The unicode string can include characters of all different locales at once, so the unicode strings are again locale-indendent as ASCII strings were, right? Well, it is almost right. But to be absolutely correct, the answer is still NO.

    The only problem I know that makes Unicode uppercase conversion locale-dependent is the case of dotless i (ı, $0131) and dotted I (İ, $0130). In most languages the upper of i ($69) is I ($49), but in turkish locale i ($69) maps to İ ($0130). Similarly in turkish the lower of I ($49) is ı ($0131).

    Now let us go back to Delphi. The new string format containes no locale information for unicode strings. We have 2 functions to make the unicode uppercase conversion – the already mentioned SysUtils.AnsiUpperCase introduced for backward compatibility and new ToUpper function defined in Character unit. The SysUtils.AnsiUpperCase is a wrapper for WinAPI CharUpperBuffW function and ignores locale-specific issues. The CharUpperBuffW works much better than its ANSI analog CharUpperBuffA, but still can’t help with “turkish case”. The Character.ToUpper function is a wrapper for LCMapString function and is locale-dependent, but the locale parameter is set to system locale. So if you need “turkish uppercase” on the system with different locale (or want to make the result of uppercase independent from system locale) you must write your own LCMapString wrapper.

    BTW: the early Delphi 2009 releases containes side-effect bug in ToUpper and ToLower implementations. The bug was fixed in Update 3 (build 12.0.3420.21218).

    Мой сайт

    AnsiExtractQuotedStr(var Src: PChar; Quote: Char): string — делает то же, что и функция AnsiDequotedStr, но результат возвращается вместо исходной строки, которая имеет тип PChar.

    AnsiPos(const Substr, S: string): Integer — выполняет те же действия, что и функция Pos, но в отличие от нее поддерживает работу с многобайтовой MBCS-кодировкой.

    AnsiSameCaption(const Text1, Text2: string): Boolean — сравнивает две строки, не делая различие между заглавными и строчными буквами, а также не учитывая символ ‘&’; учитывает местный язык.

    AnsiSameStr(const S1, S2: string): Boolean — сравнивает строки, делая различие между строчными и заглавными буквами; учитывает местный язык.

    AnsiSameText(const S1, S2: string): Boolean — сравнивает строки, не делая различие между строчными и заглавными буквами; учитывает местный язык.

    CompareStr(const S1, S2: string): Integer — выполняет сравнение двух строк, делая различие между строчными и заглавными буквами; не учитывает местный язык. Возвращаемое значение меньше нуля, если S1 S2.

    DateTimeToStr(const DateTime: TDateTime): string — преобразует значение даты и времени в строку.

    DateTimeToString(var Result: string; const Format: string; DateTime: TDateTime) — преобразует значение даты и времени в строку, выполняя при этом форматирование в соответствии со значением строки Format. Управляющие символы строки Format подробно описаны в справочнике по среде Delphi.

    Format(const Format: string; const Args: array of const): string — форматирует строку в соответствии с шаблоном Format, заменяя управляющие символы шаблона на значения элементов открытого массива Args. Управляющие символы подробно описаны в справочнике по среде Delphi.

    BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string — преобразует булевское значение в строку. Если параметр UseBoolStrs имеет значение False, то результатом работы функции является одно из значений ‘0’ или ‘-1’. Если же параметр UseBoolStrs имеет значение True, то результатом работы является одно из значений ‘FALSE’ или ‘TRUE’ (программист может задать другие значения; о том, как это сделать, читайте в справочнике по системе Delphi).

    IntToHex(Value: Integer; Digits: Integer): string — возвращает шестнадцатиричное представление целого числа Value. Параметр Digits задает количество цифр результирующей строки.

    IsDelimiter(const Delimiters, S: string; Index: Integer): Boolean — проверяет, является ли символ S[Index] одним из символов строки Delimiters. Функция поддерживает работу с многобайтовой MBCS-кодировкой.

    IsValidIdent(const Ident: string): Boolean — возвращает True, если строка Ident является правильным идентификатором языка Delphi.

    LastDelimiter(const Delimiters, S: string): Integer — возвращает индекс последнего вхождения одного из символов строки Delimiters в строку S.

    QuotedStr(const S: string): string — преобразует исходную строку в строку, взятую в одиночные кавычки; внутри строки символы кавычки дублируются.

    SameText(const S1, S2: string): Boolean — сравнивает строки, не делая различие между строчными и заглавными буквами; учитывает местный язык.

    StringOfChar(Ch: Char; Count: Integer): string — возвращает строку, в которой повторяется один и тот же символ. Количество повторений задается параметром Count.

    StrToBool(const S: string): Boolean — преобразует строку в булевское значение.

    StrToBoolDef(const S: string; const Default: Boolean): Boolean — преобразует строку в булевское значение. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.

    StrToDate(const S: string): TDateTime — преобразует строку со значением даты в числовой формат даты и времени.

    StrToDateDef(const S: string; const Default: TDateTime): TDateTime — преобразует строку со значением даты в числовой формат даты и времени. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.

    StrToDateTimeDef(const S: string; const Default: TDateTime): TDateTime — преобразует строку в числовое значение даты и времени. В случае невозможности преобразования, функция возвращает значение, переданное через параметр Default.

    StrToInt(const S: string): Integer — преобразует строку в целое число. Если строка не может быть преобразована в целое число, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).

    StrToIntDef(const S: string; Default: Integer): Integer — преобразует строку в целое число. Если строка не может быть преобразована в целое число, функция возвращает значение, заданное параметром Default.

    StrToInt64(const S: string): Int64 — 64-битный аналог функции StrToInt — преобразует строку в 64-битное целое число. Если строка не может быть преобразована в 64-битное число, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).

    StrToTime(const S: string): TDateTime — преобразует строку в числовой формат времени. Если строка не может быть преобразована в числовой формат времени, функция генерирует исключительную ситуацию класса EConvertError (обработка исключительных ситуаций рассматривается в главе 4).

    StrToTimeDef(const S: string; const Default: TDateTime): TDateTime — преобразует строку в числовой формат времени. В случае ошибки преобразования, функция возвращает значение, заданное параметром Default.

    Trim (const S: WideString): WideString — Unicode-аналог функции Trim — возвращает часть строки S без лидирующих и завершающих пробелов и управляющих символов.

    TrimLeft (const S: string): string — возвращает часть строки S без лидирующих пробелов и управляющих символов.

    TrimLeft (const S: WideString): WideString — Unicode-аналог функции TrimLeft — возвращает часть строки S без лидирующих пробелов и управляющих символов.

    TrimRight (const S: string): string — возвращает часть строки S без завершающих пробелов и управляющих символов.

    TrimRight (const S: WideString): WideString — Unicode-аналог функции TrimRight — возвращает часть строки S без завершающих пробелов и управляющих символов.

    UpperCase (const S: string): string — преобразует все строчные буквы строки S в заглавные; не учитывает местный язык (в преобразовании участвуют лишь символы в диапазоне от ‘a’ до ‘z’).

    WideFormat (const Format: WideString; const Args: array of const): WideString — Unicode-аналог функции Format, учитывающий символы местного языка, — форматирует строку в соответствии с шаблоном Format, заменяя управляющие символы в шаблоне на значения элементов открытого массива Args. Управляющие символы подробно описаны в справочнике по системе Delphi.

    WideFmtStr (var Result: WideString; const Format: WideString; const Args: array of const) — аналог функции WideFormat. Отличие в том, что WideFmtStr возвращает результат через параметр Result, а не как значение функции.

    WideLowerCase (const S: WideString): WideString — Unicode-аналог функции LowerCase (учитывает местный язык) — преобразует все заглавные буквы строки S к строчным буквам

    WideSameCaption (const Text1, Text2: WideString): Boolean — Unicode-аналог функции AnsiSameCaption — сравнивает две строки, не делая различие между строчными и заглавными буквами, а также не учитывая символ ‘&’; учитывает местный язык.

    WideSameStr (const S1, S2: WideString): Boolean — Unicode-аналог стандартной операции сравнения строк — сравнивает две строки, делая различие между строчными и заглавными буквами.

    WideSameText (const S1, S2: WideString): Boolean — Unicode-аналог функции SameText (учитывает местный язык) — сравнивает строки, не делая различие между строчными и заглавными буквами.

    WideUpperCase (const S: WideString): WideString — Unicode-аналог функции UpperCase (учитывает местный язык) — преобразует все строчные буквы строки S в заглавные.

    WrapText (const Line: string; MaxCol: Integer = 45): string — разбивает текст Line на строки, вставляя символы переноса строки. Максимальная длина отдельной строки задается параметром MaxCol.

    WrapText (const Line, BreakStr: string; const BreakChars: TSysCharSet; MaxCol: Integer): string — более мощный аналог предыдущей функции — разбивает текст Line на строки, вставляя символы переноса строки.

    AnsiToUtf8 (const S: string): UTF8String — перекодирует строку в формат UTF8.

    PUCS4Chars (const S: UCS4String): PUCS4Char — возвращает указатель на первый символ строки формата UCS-4 для работы со строкой, как с последовательностью символов, заканчивающейся символом с кодом нуль.

    StringToWideChar (const Source: string; Dest: PWideChar; DestSize: Integer): PWideChar — преобразует стандартную строку к последовательности Unicode-символов, завершающейся символом с кодом нуль.

    UCS4StringToWideString (const S: UCS4String): WideString — преобразует строку формата UCS-4 к строке формата Unicode.

    Utf8Decode (const S: UTF8String): WideString — преобразует строку формата UTF-8 к строке формата Unicode.

    Utf8Encode (const WS: WideString): UTF8String — преобразует строку формата Unicode к строке формата UTF-8.

    Utf8ToAnsi (const S: UTF8String): string — преобразует строку формата UTF-8 к стандратной строке.

    WideCharLenToString (Source: PWideChar; SourceLen: Integer): string — преобразует строку формата Unicode к стандартной строке. Длина исходной строки задается параметром SourceLen.

    WideCharLenToStrVar (Source: PWideChar; SourceLen: Integer; var Dest: string) — аналог предыдущей функции — преобразует строку формата Unicode к стандартной строке. Длина исходной строки задается параметром SourceLen, а результат возвращается через параметр Dest.

    WideCharToString (Source: PWideChar): string — преобразует последовательность Unicode-символов, завершающуюся символом с кодом нуль, к стандартной строке.

    WideCharToStrVar (Source: PWideChar; var Dest: string) — аналог предыдущей функции — преобразует последовательность Unicode-символов, завершающуюся символом с кодом нуль, к стандартной строке. Результат возвращается через параметр Dest.

    WideStringToUCS4String (const S: WideString): UCS4String — преобразует строку формата Unicode к строке формата UCS-4

    Илон Маск рекомендует:  Что такое код printer_delete_pen
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL