Работа со строками lazarus

Содержание
  1. Функции для работы со строками
  2. Объединение (конкатенация) строк
  3. Длина строки
  4. Поиск в строке
  5. Получение подстроки
  6. Удаление части строки
  7. Преобразование символов строки в строчные и в заглавные
  8. Contents
  9. Введение
  10. Инструкции для пользователей
  11. FPC не юникодный
  12. Преобразование между ANSI и юникодом
  13. Строки WideString и AnsiString
  14. Работа со строками и символами UTF-8
  15. Поиск подстроки
  16. Доступ к символам UTF-8
  17. Доступ к n-му символу UTF-8
  18. Получение кодов символов при помощи UTF8CharacterToUnicode
  19. UTF-8 Copy, Length, LowerCase и т.п.
  20. Работа с именами файлов и каталогов
  21. Восточно-азиатские языки в Windows
  22. Особенности Free Pascal
  23. UTF-8 и исходные файлы — отсутствие BOM
  24. Основы юникода
  25. Lazarus/LCL обычно использует только UTF-8
  26. Перевод интерфейса Win32 на юникод
  27. Обзор
  28. Win9x не поддерживает юникод
  29. Функции, требующие версий Ansi и Wide
  30. Снимки экрана
  31. Опрос
  32. Рубрики
  33. Работа со строками
  34. Структура строк
  35. Строка ShortString
  36. Строка WideString
  37. Строка PChar
  38. Строка PWideChar
  39. Методы обработки строк
  40. Строки String
  41. Средства модуля System
  42. Средства модуля SysUtils
  43. Примеры
  44. Строки PChar

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

Функции для работы со строками

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

А для того, чтобы посмотреть работу функций на практике, создадим новое приложение . Это будет простое приложение с единственной кнопкой посреди окна. Сохраните проект в папку 06-01, поскольку проект будет совсем простой, имена модуля и проекта можно оставить без изменений. Сгенерируйте событие нажатия на кнопку, в этом событии мы и будем экспериментировать над строками.

Объединение (конкатенация) строк

Программисту довольно часто приходится в коде объединять несколько строк в одну. Мы уже делали подобное объединение в прошлых лекциях. Для объединения служит оператор " + ":

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

Здесь, в переменной s1 мы собрали строку из 5 кусочков, причем два из них — символы перехода на новую строку. Сохраните проект, скомпилируйте его и убедитесь, что полученное сообщение будет трехстрочным.

Функция Concat() делает то же самое — объединяет строки. Её синтаксис такой (в квадратные скобки принято помещать необязательные параметры функций):

Длина строки

Поскольку мы предоставляем пользователям возможность вводить различные строки, нередко возникает необходимость выяснить длину этих самых строк. Для этого существует функция Length() . Её синтаксис :

где S — строка. Функция возвращает нам размер количество символов в этой строке. Однако в Lazarus не все так просто. Давайте изменим предыдущий код обработчика кнопки на следующий:

Поскольку результатом работы функции Length() будет целое число — количество символов, то для вывода этих данных на экран нам приходится преобразовать полученное число в строковый тип, что мы и делаем в коде

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

  1. Length() — вычисление размера строки s1 .
  2. IntToStr() — преобразование полученного в №1 результата из целого числа в строку.
  3. ShowMessage() — вывод преобразованного в №2 результата на экран.

Если вы откомпилируете проект и запустите его на выполнение, то получите результат: 5. Столько символов в строке " Hello ". Однако измените эту строку на " Привет " и снова выполните программу:

Мы ожидаем получить число 6 — количество символов в слове "Привет", но неожиданно получаем 12! Дело в том, что функция работает с ANSI -строками, то есть с теми, что занимают по 1 байту на символ. А кириллица — это не ANSI а UTF8, и требует по 2 байта на символ! Как быть? В подобных случаях используйте UTF8-аналоги строковых функций. То есть, вместо Length() используйте UTF8Length() . Эта функция гарантированно вернет количество символов в строке, на каком бы языке эти символы не вводились. Но для использования UTF8Length() нужно подключить модуль LCLProc , где и реализованы все UTF8-функции.

Пролистайте код выше, на начало модуля, и добавьте LCLProc в раздел uses:

Теперь мы можем изменить наш обработчик:

Вот теперь мы получим в результате число 6.

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

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

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

  • Pos() — для ANSI-символов
  • UTF8Pos() — для кириллицы (UTF8-символы) — требует подключения модуля LCLProc

Здесь Substr — искомый текст; Str — строка, в которой ищется текст. Функции возвращают в качестве результата целое число . Если искомый текст в строке отсутствует, обе функции вернут ноль. Иначе — номер символа строки, с которого начинается найденная подстрока . Переделаем код обработчика кнопки ( модуль LCLProc у нас уже подключен):

Запустив программу на выполнение, убедимся, что функция

возвращает результат 3 — номер первого символа искомой подстроки в строке " Привет ".

Если в строке содержится несколько искомых подстрок, функции вернут номер первого такого вхождения. А если для строки с русскими буквами использовать функцию Pos() вместо UTF8Pos() , результат будет неверный.

Получение подстроки

Чтобы из строки получить ее часть (подстроку), применяют функции

  • Copy() — для ANSI-символов
  • UTF8Copy() — для кириллицы — требует подключения модуля LCLProc

Здесь Str — строка исходного текста; StartCharIndex — номер первого символа подстроки; Count — количество символов подстроки. Снова переделаем обработчик кнопки:

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

из строки " Привет " вернет " ив " — подстроку, начиная с третьего символа, размером два символа.

Если для кириллицы вместо UTF8Copy() использовать Copy() , результат будет неверным.

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

Для удаления части строки применяют функции Delete() и UTF8Delete() .

Здесь Str — строка исходного текста; StartCharIndex — номер первого символа удаляемой подстроки; Count — количество удаляемых символов. Эта функция отличается от других тем, что она изменяет исходную строку Str , обрезает ее. Другие функции оставляли эту строку без изменений. Итак, наш новый код:

Функцией UTF8Delete(s1, 3, 2) мы ампутировали строку s1 , вырезали из нее, начиная с третьего символа, подстроку размером 2 символа. В результате у нас осталась строка " Прет ". Как и с предыдущими функциями, применение с кириллицей не UTF8-варианта исказит результат.

Преобразование символов строки в строчные и в заглавные

Иногда требуется сравнить две строки, или найти какую-то подстроку. Но не всегда известно, в каком регистре пользователь ввел текст. К примеру, нам нужно узнать, ввел ли пользователь слово "Москва", или что-то другое. Пользователь знает, что он должен ввести название нашей столицы, однако он может полениться нажать , и в результате введет "москва". Или нажмет и введет "МОСКВА". А поскольку слово он написал без ошибок, то уверен, что все сделал правильно. Но мы-то ожидаем не просто слово , а слово со строго определенным описанием! К сожалению, пользователи далеко не всегда вводят то, что нужно, и программистам приходится идти на всевозможные хитрости, чтобы добиваться нужного результата. Например, мы можем заранее преобразовать введенное пользователем слово в верхний регистр (то есть, сделать все буквы заглавными), и сравнить его со словом "МОСКВА". И какие бы буквы пользователь первоначально не вводил, результат все равно будет верным.

Читайте также:  Фотография 10х15 в дюймах

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

Contents

Введение

Начиная с 0.9.25 Lazarus полностью поддерживает юникод (Unicode) на всех платформах, исключая Gtk 1. На этой странице размещены инструкции для пользователей Lazarus, планы на будущее, описаны основные концепции и детали реализации.

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

Хотя в Lazarus есть юникодные наборы виджетов, важно отметить, что не всё в юникоде. Кодировка строк и правильное преобразование между библиотеками, ожидающими разные кодировки, является ответственностью разработчика.

Обычно библиотекой используется единая кодировка строк (речь о динамической библиотеке DLL или пакете Lazarus). Каждая библиотека обычно ожидает одну кодировку, которой может быть юникод (UTF-8 для Lazarus) или ANSI (что означает системную кодировку, которая может быть UTF-8 или другой). RTL и FCL в FPC версий 2.4-2.6 ожидают строки ANSI.

Преобразование между юникодом и ANSI возможно при помощи функций UTF8ToAnsi и AnsiToUTF8 модуля System или UTF8ToSys и SysToUTF8 модуля FileUtil (Lazarus). Последние две мощнее (быстрее), но добавят к программе больше кода.

FPC не юникодный

Библиотеки Free Pascal времени исполнения (RTL) и свободных компонентов (FCL) в текущих версиях FPC (по 2.6.1) используют ANSI, поэтому требуется преобразование строк, получаемых из юникодных или переделываемых в юникодные библиотек (например, LCL).

Преобразование между ANSI и юникодом

Допустим, нужно передать в файловую функцию из RTL строку, полученную из TEdit:

И в обратную сторону:

Важно: UTF8ToAnsi возвратит пустую строку, если строка в UTF-8 содержит неверные символы.

Важно: AnsiToUTF8 и UTF8ToAnsi требуют менеджера "широких" строк (widestring) в Linux, BSD и macOS. Можно воспользоваться функциями SysToUTF8 или UTF8ToSys (из модуля FileUtil) или добавить менеджер, включив cwstring одним из первых модулей в разделе uses программы.

Строки WideString и AnsiString

WideString — это строковый тип, у которого базовый элемент данных имеет размер 2 байта. Строки этого типа почти всегда в кодировке UTF-16. См. Widestrings

Обратите внимание, что при доступе к WideString как к массиву, каждый его элемент представлен 2 байтами, а символ в UTF-16 может состоять из 1 или 2 элементов, занимающих соответственно 2 или 4 байта. Поэтому при доступе к WideString как к массиву совершенно неправильно ожидать соответствия "один элемент — один символ", наличие в строке 4-х байтовых символов приведёт к ошибкам. Заметьте также, что UTF-16 как и UTF-8, допускает составные (decomposed) символы. Например, символ "Á" может быть представлен как одним элементом, так и парой: "A" + изменяющий акцент. Таким образом, включающий акцентированные буквы текст в юникоде часто может быть закодирован различными способами, Lazarus и FPC не обрабатывают такие случаи автоматически.

При передаче AnsiString в качестве WideString требуется преобразование кодировки.

Работа со строками и символами UTF-8

В Lazarus до версии 0.9.30 включительно функции LCL для работы с UTF-8 находились в модуле LCLProc. В Lazarus 0.9.31 и последующих они в целях совместимости по-прежнему доступны при подключении LCLProc, но сам код работы с UTF-8 находится в модуле lazutf8 пакета lazutils.

Для выполнения операций над строками в UTF-8 используйте функции модуля lazutf8 вместо предоставляемых модулем SysUtils из FPC, поскольку SysUtils не готов для работы с юникодом, а lazutf8 готов. Просто замените утилиты из SysUtils на эквивалентные из lazutf8, имеющие те же имена с префиксом UTF-8.

Учтите также, что перебор символов как элементов строки-массива не подходит для юникода. Эта особенность присуща не только UTF-8, юникод не предполагает фиксированный размер каждого символа. Возможны два основных способа перебора символов строки в кодировке UTF-8:

  • побайтовый — подходит для поиска подстроки или поиска ASCII символов в строке UTF-8, например, при разборе файлов XML.
  • посимвольный — подходит для экранных компонентов, таких как synedit, когда, например, нужно определить третий символ, отображаемый на экране.

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

Благодаря особенностям UTF-8 для поиска подстроки подходят обычные функции поиска подстроки. Несмотря на мультибайтность, первый байт не может быть спутан со вторым. Поэтому поиск корректной подстроки в UTF-8 при помощи Pos всегда возвращает правильную позицию с точки зрения UTF-8:

Из-за неоднозначности юникода возможно неожиданное поведение Pos() (как и любых сравнений), если одна из строк содержит составные (decomposed) символы, а другая — их непосредственные коды. RTL не обрабатывает такие случаи автоматически.

Доступ к символам UTF-8

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

Доступ к n-му символу UTF-8

Иногда помимо последовательного требуется и произвольный доступ к символам UTF-8.

Получение кодов символов при помощи UTF8CharacterToUnicode

Пример демонстрирует получение 32-битного кода каждого символа строки в UTF-8:

UTF-8 Copy, Length, LowerCase и т.п.

В модуле lazutf8 (LCLProc для Lazarus 0.9.30 и ранее) реализованы практически все операции над строками в UTF-8. Ниже приведён список утилит из lazutf8.pas:

Работа с именами файлов и каталогов

Элементы управления и функции Lazarus ожидают имена файлов и каталогов в кодировке UTF-8, но RTL использует для таких имён строки в ANSI.

Например, пусть кнопка назначает текущий каталог свойству Directory элемента TFileListBox. Функция RTL GetCurrentDir использует ANSI, а не юникод, поэтому требуется преобразование:

Модуль FileUtil содержит общие файловые функции в варианте UTF-8:

Восточно-азиатские языки в Windows

Шрифт элементов управления пользовательского интерфейса по умолчанию (Tahoma) в Windows XP в состоянии правильно отображать несколько письменностей/алфавитов/языков, включая арабский, русский (кириллица) и западноевропейские языки (латинский/греческий алфавиты), но не восточно-азиатские как китайский, японский и корейский.

Для корректного отображения указанных языков стандартным шрифтом достаточно в Панели управления выбрать Региональные настройки, щёлкнуть вкладку Языки и установить поддержку восточно-азиатских языков. Естественно, что в версиях Windows XP на указанных языках этот пакет включён по умолчанию. Дополнительные инструкции здесь.

Более позднее версии Windows скорее всего не требуют установки дополнений для поддержки указанных языков.

Особенности Free Pascal

UTF-8 и исходные файлы — отсутствие BOM

Когда в созданном в Lazarus файле исходного кода используются не-ASCII символы, он сохраняется в UTF-8. При этом не используется BOM (Byte Order Mark — маркер порядка байтов). Кодировку можно изменить при помощи правого щелчка по редактору кода / File Settings / Encoding. Помимо того, что файлы в UTF-8 не обязаны иметь BOM, причина его отсутствия скорее в том, как FPC обрабатывает строки AnsiString. LCL использует AnsiString для совместимости и UTF-8 для переносимости.

Примечание. Некоторые текстовые редакторы в MS Windows могут полагать, что файлы используют системную кодовую страницу (кодировку OEM) и отображают в них неправильные символы. Не добавляйте BOM. Если добавить BOM, то придётся изменить все строковые присваивания.

Когда отсутствует BOM (и кодировка не задана параметром) компилятор считает, что строка в системной кодировке и копирует каждый байт в строку без преобразований. LCL ожидает строки именно в таком виде.

Основы юникода

Стандарт Unicode сопоставляет целые от 0 до 10FFFF(h) символам. Каждое такое сопоставление именуется кодовой точкой (code point). Другими словами, юникодные символы определены для кодовых точек от U+000000 до U+10FFFF (от 0 до 1 114 111).

Для представления кодовых точек как уникальных байтовых последовательностей существуют три основных схемы. Эти схемы называют форматами юникодных преобразований: UTF-8, UTF-16 и UTF-32. Преобразование между всеми ними возможно. Их основные свойства:

Читайте также:  Где находится свойства папки в windows 7

UTF-8 обладает несколькими важными и полезными свойствами: Содержимое интерпретируется как последовательность байтов, поэтому понятие порядка байт "от младшего" или "от старшего" отсутствует. Юникодные символы от U+0000 до U+007F (ASCII) кодируются байтами от 00h до 7Fh (совместимо с ASCII). Это значит, что файлы и строки, содержащие только 7-битные символы ASCII, кодируются одинаково в ASCII и в UTF-8. Все символы больше U+007F кодируются как последовательность нескольких байтов, у каждого из которых старшие биты установлены в 1. Последовательность байт одного символа заведомо не содержится в более длинной последовательности байт другого символа. Это позволяет без затруднений искать подстроки. Первый байт мультибайтовой последовательности (представляющей не-ASCII символ) всегда принадлежит диапазону от C0h до FDh и показывает количество последующих байт для этого символа. Все последующие байты мультибайтной последовательности принадлежат диапазону от 80h до BFh. Это позволяет легко выполнять ресинхронизацию и способствует надежности.

UTF-16 обладает следующими важными свойствами: Используется одно 16-битное слово для кодирования символов от U+0000 до U+d7ff и два 16-битных слова для кодирования всех остальных символов.

В заключение, любой юникодный символ возможно представить как один 4-байтный/32-битный элемент в UTF-32.

Lazarus/LCL обычно использует только UTF-8

Начиная с Lazarus 0.9.31 интерфейс GTK1 объявлен устаревшим, все интерфейсы LCL совместимы с юникодом, Lazarus и LCL используют строки только в кодировке UTF-8, если явно не указано, что функция/процедура принимает другие кодировки.

Перевод интерфейса Win32 на юникод

Обзор

Сперва, и это самое важное, во избежание поломки существующего интерфейса ANSI следует все юникодные интерфейсные модификации заключить в IFDEF WindowsUnicodeSupport. После стабилизации модификаций все IFDEF-ы будут убраны и останется только юникодная часть. К тому моменту все существующие программы, использующие символы ANSI, потребуют миграции на юникод.

Win9x не поддерживает юникод

Платформы Широкие функции, присутствующие в Windows 9x

Некоторые функции широкого API присутствуют в Windows 9x. Вот список таких функций: http://support.microsoft.com/kb/210341

Функции, требующие версий Ansi и Wide

Снимки экрана

Почему LCL не использует кодовые страницы для исходных текстов?

-Fcutf8 и <$codepage utf8>существуют не первый год.

Следующие программы требуют FPC 2.7.1. Описанные трудности существуют и на более старых компиляторах.

Есть в использовании -Fcutf8 и <$codepage utf8>несколько ловушек. Директивы работают, если DefaultSystemCodePage из RTL возвращает CP_UTF8. Иначе компилятор перекодирует строки. Например, в Linux умолчание для RTL — CP_ACP, что по умолчанию ISO_8859-1. RTL самостоятельно не читает язык из переменных окружения. Поэтому умолчанием будет ISO_8859-1. Это означает, что строковые константы в UTF-8 будут преобразованы компилятором.

Откомпилируйте с -Fcutf8 и запустите в Linux с LANG в utf-8:

LCL использует widestringmanager — менеджер широких строк (в настоящее время cwstring), который назначает DefaultSystemCodePage. Тоже самое можно сделать и в не-LCL программах:

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

Посмотрите, работают строковые константы в UTF-8, строковые константы с кодами UTF-8, но не их комбинация. Приведённый выше код скомпилирован с -Fcutf8 и использует cwstring для установки DefaultSystemCodePage в CP_UTF8.

Так что же пошло не так?

Компилятор обрабатывает строковые не-ASCII константы (здесь — ä) как широкие строки (UCS2, не UTF-16).

Одурачить компилятор при помощи ‘ä=’+#$C3#$A4 не выйдет. Придётся определить две отдельные строковые константы.

Использование символов не из диапазона UCS-2 приведёт к

Но можно указать их в кодах UTF-16: #$D834#$DD1E. Да, прочитали правильно. Указание кодовой страницы при помощи -Fcutf8 или <$codepage utf8>действительно определяет смесь UTF-8 и UTF-16.

Теперь откомпилируйте приведённый выше код без -Fcutf8:

Вот это да, всё как хотелось. Можно даже смешивать строковые константы в ASCII и не-ASCII. Без указания кодовой страницы компилятор просто сохраняет строковые константы как последовательности байтов. А это и есть UTF-8.

В этом одна из причин того, почему LCL приложения не используют флаги кодировок.

В msegui реализована экосистема широких строк, которая работает лучше, чем кодовые страницы.

Эксперимент — требуется тестирование под Windows!

Обычно RTL использует для строк системную кодовую страницу (например, FileExists или TStringList.LoadFromFile). Под Windows RTL не использует юникод, вам недоступны символы вне вашей языковой группы. LCL работает с кодировкой UTF-8, поддерживающей все символы юникода. Под Linux и macOS системной кодовой страницей обычно является UTF-8, поэтому для них RTL по умолчанию использует CP_UTF8.

Начиная с FPC 2.7.1 кодовая страница, используемая RTL по умолчанию, может быть изменена на UTF-8 (CP_UTF8). Таким образом, пользователи Windows теперь смогут использовать в RTL строки UTF-8. Для тестирования добавьте -dEnableUTF8RTL в Lazarus build options (параметры сборки проекта) и пересоберите проект.

  • Например, FileExists и aStringList.LoadFromFile(Filename) теперь полностью поддерживают юникод. Полный перечень функций, уже поддерживающих юникод полностью, смотрите по ссылке:
  • AnsiToUTF8, UTF8ToAnsi, SysToUTF8, UTF8ToAnsi не действуют. Они использовались преимущественно для вышеуказанных функций, которые больше не требуют преобразований аргументов и результата.
  • Многочисленные явные вызовы UTF8Encode и UTF8Decode больше не нужны, поскольку при присваивании строки в UnicodeString строке String и наоборот компилятор сделает это автоматически.
  • При обращении к WinAPI необходимо использовать функции с "W" либо пользоваться функциями UTF8ToWinCP и WinCPToUTF8.
  • Включить новый режим можно перекомпилировав Lazarus с -dEnableUTF8RTL.
  • Если используете строковые литералы с WideString, UnicodeString или UTF8String, то теперь исходные тексты должны быть в соответствующей кодировке. Например, можно использовать исходные тексты в UTF-8 (поведение Lazarus по умолчанию) и передавать компилятору параметр -FcUTF8.
  • "String" и "UTF8String" — разные типы. При присваивании String переменной в UTF8String компилятор добавляет код проверки соответствия кодировок. Это повлечёт увеличение времени исполнения и размера машинного кода.
Реклама на сайте

Опрос

Рубрики

Подписка

Работа со строками

Структура строк

L – длина строки. В структурах строк верхняя строка – байты строки, нижняя – номера байтов.

Строка ShortString

Используется кодировка ANSI. Строка размещается компилятором в статической памяти. Для одного символа отводится 1 байт. Под строку ShortString выделяется память размером L+1 байт.

L C C C C C C C C C C C
0 1 2 3 . . L

Строка WideString

Используется кодировка Unicod. Строка размещается в динамической памяти. Для одного символа отводится 2 байта. В статической памяти компилятор создает указатель размером в 4 байта, в который при создании строки заносится адрес ее начала. Указатель до создания строки и после ее удаления содержит nil – признак отсутствия данных. Под строку WideString всего выделяется память размером L*2+4 байт.

L L L L C C C C
0 1 2 3 . . . . . . L/2+3

L 30 . В два раза меньше, чем у AnsiString

Строка PChar

Используется кодировка ANSI. Это нуль-терминальная строка. Признаком ее конца является код #0. Строка размещается в динамической памяти. Для одного символа отводится 1 байт. В статической памяти компилятор создает указатель размером в 4 байта, в который при создании строки заносится адрес ее начала. Указатель до создания строки и после ее удаления содержит nil – признак отсутствия данных. Под строку PCar всего выделяется память размером L+1 байт.

L L L L C C C C C C C #0
0 1 2 3 . L L+1

L не ограничена

Строка PWideChar

Используется кодировка Unicod. Это нуль-терминальная строка. Признаком ее конца является код #0. Строка размещается в динамической памяти. Для одного символа отводится 2 байта. В статической памяти компилятор создает указатель размером в 4 байта, в который при создании строки заносится адрес ее начала. Указатель до создания строки и после ее удаления содеожит nil – признак отсутствия данных. Под строку PWideCar всего выделяется память размером L*2+1 байт.

С С С С С #0
0 1 2 3 L*2. L*2+1

Методы обработки строк

В модулях System, SysUtils, Strings определены методы для обработки строк. Функциональное назначение методов:

  • Создание и удаление строк.
  • Копирование и объединение.
  • Длина и позиционирование.
  • Представление строки.
  • Преобразования строки в иной тип.
  • Преобразования иного типа в строку.
  • Сравнение строк.
Читайте также:  Роутер от мегафон: сброс настроек

Ниже рассмотрены наиболее часто используемые методы.

Строки String

Средства модуля System

Вызов Описание
Chr(N) Символ ASCII c номером N.
Concat(S1,S2,SN) Конкатенация строк S1, S2 …SN.
Copy(S, I, Count) Копирует Count символов строки S с номера I.
Delete(S, I,C) Удаляет С символов строки S с номера I.
Insert(S1,S2, I) Ввести подстроку S2 в строку S1, начиная с позиции I.
Length(S) Длина строки S.
LowerCase(S) Строка S в нижнем регистре.
Pos(S1,S2) Позиция подстроки S1 в строке S2
Str(X; S) Преобразовать число X в строку S.
StringOfChar(C, Count) Строка из Count символов C.
UpCase(S) Cтрока S в верхнем регистре.
Val(S,V, C) Преобразует строку S в число V. При ошибке в C заносится номер ошибочного символа строки S.

Средства модуля SysUtils

Вызов Действие
IntToStr(V) Превращает целое число V в строку.
StrToInt(S) Превращает строку S в целое число.
StrToFloat(S) Превращает строку S в число.
FloatToStr(V) Превращают число V в строку.
FloatToStrF(V,Format) Превращают число V в строку, используя формат вывода Format.

В функции FloatToStrF Format может принимать значения:

  • ffcurrency – денежный,
  • ffExponent – научный,
  • ffFixed – фиксированный,
  • ffGeneral – обобщенный, с самым коротким результатом,
  • ffNumber – фиксированный с разделителями тысяч.

Примеры

Пример 1 . Создание строк.

uses SysUtils; // Ссылка на модули

Str:=’123456789’; // Cтрока Str

Index:=5; // Начальная позиция (счет с 1)

Count:=3; // Сколько символов

Delete(Str,Index,Count); // Удаление 3-х символов

Substr:=StringOfChar(‘A’,4); // Подстрока Substr = ‘AAAA’

Insert(Substr,Str,Index); // Ввод Substr в Str с позиции 5

readln; // Пауза, смотрю результат

Пример 2 . Копирование и объединение строк.

uses SysUtils; // Ссылка на модули

Source:=’ABCD’; // Строка источник

Index:=5; // Начальная позиция (счет с 1)

Count:=3; // Сколько символов

writeln(S1); // Ответ 12345

writeln(Source); // Ответ ABCD

S1:=Concat(S1,Source); // Вызов функции конкатенации

writeln(S1); // Ответ 12345ABCD

S1:=S1+Source; // Операция конкатенации

writeln(S1); // Ответ 12345ABCDABCD

S2:=Copy(S1,Index,Count); // Копирование подстроки

writeln(S2); // Ответ 5AB

readln; // Пауза, смотрю результат

Пример 3 . Длина и позиционирование.

uses SysUtils; // Ссылка на модули

L:=Length(S); // Определение длины строки

writeln(L); // Ответ 9.

P:=Pos(SubStr,S); // Определение позиции подстроки.

writeln(P); // Ответ 5.

readln; // Пауза, смотрю результат

Пример 4 . Преобразования String в иной тип

uses SysUtils; // Ссылка на модули

Str(x:7:3,Str); // Число => строка

writeln(Str); // Ответ 123.450 (3 дробных позиции)

Str(x,Str); // Число => строка

writeln(S); // Ответ 1.2345000000E+02

Val(Str,Val,Code); // Строка => число

writeln(Val); // Ответ 1.2345000000E+02

Val(’123Z’,Val,Code); // Строка => число с ошибкой

writeln(Val,Code); // Ответ 4 – номер позиции с ошибкой

readln; // Пауза, смотрю результат

Пример 5 . Преобразования иного типа в String

uses SysUtils; // Ссылка на модули

Str(X:7:3,S); // Число => строка

writeln(S); // Ответ 123.450 (3 дробных позиции)

Str(X,S); // Число => строка

writeln(S); // Ответ 1.2345000000E+02

Val(S,V,Code); // Строка => число

writeln(V); // Ответ 1.2345000000E+02

S:=FloatToStr(V,ffFixed,6,3); // Число => строка с форматом

writeln(S); // Ответ 123.450

readln; // Пауза, смотрю результат

Строки PChar

Средства обработки определены в модуле String. Строки PChar создаются в динамической памяти.

Вызов Действие
StrNew(S) Создать строку S.
StrDispose(S); Удалить строку S.
StrCopy(Dest, Source) Копирует в строку Dest строку Source.
StrECopy(Dest, Source) Копирует в строку Dest строку Source.
StrLCopy(Dest, Source, MaxLen) Копирует в строку Dest строку Source с ограничением в MaxLen числа символов в Dest.
StrMove(Dest, Source, Count) Копирует в строку Dest из строки Source Count символов с заменой.
StrCat(Dest, Sourcе) Присоединяет к строке Dest копию строки Source.
StrLCat(Dest, Source, MaxLen) Присоединяет к строке Dest копию строки Source. Число символов в результирующей строке не больше MaxLen.
StrCopy(Dest, Source) Копирует в строку Dest строку Source.
StrECopy(Dest, Source) Копирует в строку Dest строку Source.
StrLCopy(Dest, Source, MaxLen) Копирует в строку Dest строку Source с ограничением в MaxLen числа символов в Dest.
StrMove(Dest, Source, Count) Копирует в строку Dest из строки Source Count символов с заменой.
StrCat(Dest, Sourcе) Присоединяет к строке Dest копию строки Source.
StrLCat(Dest, Source, MaxLen) Присоединяет к строке Dest копию строки Source. Число символов в результирующей строке не больше MaxLen.
StrLen(Str:pChar) Возвращает длину строки без учета символа с кодом #0.
StrEnd(Str:pChar) Возвращает указатель на конец строки.
StrPos(Str1, Str2) Возвращает указатель на начало первого появления строки Str2 в Str1
StrScan(Str, Chr) Возвращает указатель на первое появление символа Chr в строке Str.
StrRScan(Str, Chr) Возвращает указатель на последнее появление символа Chr в строке Str.
StrLower(Str) Перевод строчных букв в прописные (только латинские).
StrUpper(Str) Перевод прописных букв в строчные (только латинские).
StrPas(Str) pChar -> string.
StrPCopy(Dest, Source) string -> pChar.
StrComp(Str1, Str2) Сравнивает строки. Возвращается: число 0, если Str1>Str2.
StrIComp(Str1, Str2) То же, но игнорируется разница в высоте латинских букв.
StrLComp(Str1, Str2, MaxLen) Подобна StrComp, но сравниваются первые MaxLen символов.
StrLIComp(Str1, Str2,MaxLen) Подобна StrIComp, но сравниваются первые MaxLen символов

Пример 1 . Создание и удаление строк

uses SysUtils; // Ссылка на модули

p:=StrNew(’1234′); // Создать строку (аргумент не пустой)

StrDispose(p); // Удалить строку

Пример 2 . Копирование и объединение

uses SysUtils; //Ссылка на модули

s1,s2:string; // Переменные типа string

p1,p2,p3:pChar; // Переменные типа pChar

p1:=StrNew(‘AAAAAAAAAAAAAAAA’); // Создать в ДП переменную p1

p2:=StrNew(’123456′); // Создать в ДП переменную p2

p3:=StrNew(‘abcdef’); // Создать в ДП переменную p3

StrCopy(p1,p2); // Копировать p2 в p1

s1:=StrPas(p1); // Преобразовать p1 в s1 для вывода

writeln(s1); // s1 = 123456

StrLCopy(p1,p2,4); // Копировать p2 в p1 с ограничением длины

p1:=StrMove(p1,p3,2); // Копирование из p3 2 элементов в p1 с заменой

p1:=StrLCat(p1,p2,8); // Дописать p3 в p1 с ограничением длины

readln; // Пауза, смотрю результат

Пример 3 . Длина и позиционирование

uses SysUtils; // Ссылка на модули

s1,s2:string; // Переменные типа string

p0,p1,p2:pChar; // Переменные типа pChar

L:word; // Длина строки

p1:=StrNew(’12345678′); // Создать в ДП переменную p1

p2:=StrNew(’12345′); // Создать в ДП переменную p2

L:=StrLen(p1); // Длина строки p1

p0:=p2; // Запомнить переменную p2 в p0

while p2<>StrEnd(p2) do // Повторять в цикле до конца строки

P2^:=‘!’; // Заполнить p2 знаками ”!”

Inc(p2); // Увеличить указатель

Inc(L); // Увеличить L на 1

p2:=p0; // Восстановить p2 (на начало)

s2:=StrPas(p2); // Преобразовать p2 в s2

readln; // Пауза, смотрю результат

Пример 4 . Преобразования pChar String

uses SysUtils; // Ссылка на модули

s1,s2,s3:string; // Переменные типа String

p1,p2,p3:pChar; // Переменные типа pChar

s1:=’AaBbDdЖж’; // Переменная s1

p1:=StrNew(’12345678′); // Создать в ДП переменную p1

p2:=StrNew(’12345678′); // Создать в ДП переменную p2

p3:=StrNew(’12345678′); // Создать в ДП переменную p3

p1:=StrPCopy(p1,s1); // Копировать s1 в p1

StrCopy(p2,p1) // Копировать p1 в p2

StrCopy(p3,p1); // Копировать p1 в p3

p2:=StrLower(p1); // Получить в p2 строчные буквы

p3:=StrUpper(p1); // Получить в p3 прописные буквы

s2:=StrPas(p2); // Преобразовать p2 в s2

s3:=StrPas(p3); // Преобразовать p3 в s3

writeln(s1); // s1 = AaBbDdЖж

writeln(s2); // s2 = aabbccЖж

writeln(s3); // s3 = AABBDDЖж

readln; // Пауза, смотрю результат

Пример 5 . Сравнение строк

uses SysUtils; // Ссылка на модули

p1,p2,p3,p4,p5,p6:pChar; // Переменные типа pChar

x:integer; // Для результата сравнения

p1:=StrNew(‘ABC123′); // Создать в ДП переменную p1

p2:=StrNew(‘abc123’); // Создать в ДП переменную p2

p3:=StrNew(‘ABC123′); // Создать в ДП переменную p3

p4:=StrNew(’ABC456’); // Создать в ДП переменную p4

p5:=StrNew(‘ФЫВ123′); // Создать в ДП переменную p5

p6:=StrNew(’фыв456’); // Создать в ДП переменную p6

Оцените статью
Добавить комментарий

Adblock
detector