Delphi boolean to string - IT Справочник
Llscompany.ru

IT Справочник
26 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Delphi boolean to string

Сегодня:

Последние:
— 27.12, 20:12 / #6692
— 29.03, 23:32 / #6682
— 30 апреля 2012

Сейчас онлайн:
На сайте — 34
На IRC-канале — 2

Работа со строковыми типами данных

Автор: Ерёмин Андрей
Редакция: 2

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

Строка — это последовательность символов. В Object Pascal существует несколько строковых типов. Вот основные из них:

Для большинства целей подходит тип AnsiString (иногда называется Long String).

Стандартные функции обработки строк:

1) Функция Length(Str: String) — возвращает длину строки (количество символов). Пример:

var
Str: String; L: Integer;
< . >
Str := ‘Hello!’ ;
L := Length(Str);

2) Функция SetLength(Str: String; NewLength: Integer) позволяет изменить длину строки. Если строка содержала большее количество символов, чем задано в функции, то «лишние» символы обрезаются. Пример:

var Str: String;
< . >
Str := ‘Hello, world!’ ;
SetLength(Str, 5);

3) Функция Pos(SubStr, Str: String) — возвращает позицию подстроки в строке. Нумерация символов начинается с единицы (1). В случае отсутствия подстроки в строке возращается 0. Пример:

var Str1, Str2: String; P: Integer;
< . >
Str1 := ‘Hi! How do you do?’ ;
Str2 := ‘do’ ;
P := Pos(Str2, Str1);

4) Функция Copy(Str: String; Start, Length: Integer) — возвращает часть строки Str, начиная с символа Start длиной Length. Ограничений на Length нет — если оно превышает количество символов от Start до конца строки, то строка будет скопирована до конца. Пример:

var Str1, Str2: String;
< . >
Str1 := ‘This is a test for Copy() function.’ ;
Str2 := Copy(Str1, 11, 4);

5) Процедура Delete(Str: String; Start, Length: Integer) — удаляет из строки Str символы, начиная с позиции Start длиной Length. Пример:

var Str1: String;
< . >
Str1 := ‘Hello, world!’ ;
Delete(Str1, 6, 7);

6) Процедура Insert(SubStr: String; Str: String; Pos: Integer) — вставляет в строку Str подстроку SubStr в позицию Pos. Пример:

var Str: String;
< . >
Str := ‘Hello, world!’ ;
Insert( ‘my ‘ ,Str, 8);

7) Функции UpperCase(Str: String) и LowerCase(Str: String) преобразуют строку соответственно в верхний и нижний регистры:

var Str1, Str2, Str3: String;
< . >
Str1 := ‘hELLo’ ;
Str2 := UpperCase(Str1); < Str2 = "HELLO" >
Str3 := LowerCase(Str1);

Строки можно сравнивать друг с другом стандартным способом:

var Str1, Str2, Str3: String; B1, B2: Boolean;
< . >
Str1 := ‘123’ ;
Str2 := ‘456’ ;
Str3 := ‘123’ ;
B1 := (Str1 = Str2); < B1 = False >
B2 := (Str1 = Str3);

Если строки полностью идентичны, логическое выражение станет равным True.

Дополнительные функции обработки строк:

В модуле StrUtils.pas содержатся полезные функции для обработки строковых переменных. Чтобы подключить этот модуль к программе, нужно добавить его имя (StrUtils) в раздел Uses.

1) PosEx(SubStr, Str: String; Offset: Integer) — функция аналогична функции Pos(), но позволяет задать отступ от начала строки для поиска. Если значение Offset задано (оно не является обязательным), то поиск начинается с символа Offset в строке. Если Offset больше длины строки Str, то функция возратит 0. Также 0 возвращается, если подстрока не найдена в строке. Пример:

uses StrUtils;
< . >
var Str1, Str2: String; P1, P2: Integer;
< . >
Str1 := ‘Hello! How do you do?’ ;
Str2 := ‘do’ ;
P1 := PosEx(Str2, Str1, 1); < P1 = 12 >
P2 := PosEx(Str2, Str1, 15);

2) Функция AnsiReplaceStr(Str, FromText, ToText: String) — производит замену выражения FromText на выражение ToText в строке Str. Поиск осуществляется с учётом регистра символов. Следует учитывать, что функция НЕ изменяет самой строки Str, а только возвращает строку с произведёнными заменами. Пример:

uses StrUtils;
< . >
var Str1, Str2, Str3, Str4: String;
< . >
Str1 := ‘ABCabcAaBbCc’ ;
Str2 := ‘abc’ ;
Str3 := ‘123’ ;
Str4 := AnsiReplaceStr(Str1, Str2, Str3);

3) Функция AnsiReplaceText(Str, FromText, ToText: String) — выполняет то же самое действие, что и AnsiReplaceStr(), но с одним исключением — замена производится без учёта регистра. Пример:

uses StrUtils;
< . >
var Str1, Str2, Str3, Str4: String;
< . >
Str1 := ‘ABCabcAaBbCc’ ;
Str2 := ‘abc’ ;
Str3 := ‘123’ ;
Str4 := AnsiReplaceText(Str1, Str2, Str3);

4) Функция DupeString(Str: String; Count: Integer) — возвращает строку, образовавшуюся из строки Str её копированием Count раз. Пример:

uses StrUtils;
< . >
var Str1, Str2: String;
< . >
Str1 := ‘123’ ;
Str2 := DupeString(Str1, 5);

5) Функции ReverseString(Str: String) и AnsiReverseString(Str: AnsiString) — инвертируют строку, т.е. располагают её символы в обратном порядке. Пример:

uses StrUtils;
< . >
var Str1: String;
< . >
Str1 := ‘0123456789’ ;
Str1 := ReverseString(Str1);

6) Функция IfThen(Value: Boolean; ATrue, AFalse: String) — возвращает строку ATrue, если Value = True и строку AFalse если Value = False. Параметр AFalse является необязательным — в случае его отсутствия возвращается пустая строка.

uses StrUtils;
< . >
var Str1, Str2: String;
< . >
Str1 := IfThen(True, ‘Yes’ ); < Str1 = "Yes" >
Str2 := IfThen(False, ‘Yes’ , ‘No’ );

Мы рассмотрели функции, позволяющие выполнять со строками практически любые манипуляции. Как правило, вместо строки с указанным типом данных, можно использовать и другой тип — всё воспринимается одинаково. Но иногда требуются преобразования. Например, многие методы компонент требуют параметр типа PChar, получить который можно из обычного типа String функцией PChar(Str: String):

uses ShellAPI;
< . >
var FileName: String;
< . >
FileName := ‘C:WINDOWSnotepad.exe’ ;
ShellExecute(0, ‘open’ , PChar(FileName), » , » , SW_SHOWNORMAL);

Тип Char представляет собой один-единственный символ. Работать с ним можно как и со строковым типом. Для работы с символами также существует несколько функций:

Chr(Code: Byte) — возвращает символ с указанным кодом (по стандарту ASCII):

var A: Char;
< . >
A := Chr(69);

Ord(X: Ordinal) — возвращает код указанного символа, т.е. выполняет противоположное действие функции Chr():

var X: Integer;
< . >
X := Ord( ‘F’ );

Из строки можно получить любой её символ — следует рассматривать строку как массив. Например:

var Str, S: String; P: Char;
< . >
Str := ‘Hello!’ ;
S := Str[2]; < S = "e" >
P := Str[5];

В этой статье описаны основные приёмы работы со строковыми типами данных. Как правило, этих данных достаточно для написания любого алгоритма.

Статья добавлена: 18 февраля 2006

Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.

Статьи, похожие по тематике

Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

Ссылка для форумов (BBCode):

Быстрая вставка ссылки на статью в сообщениях на сайте:
<> (буква a — латинская) — только адрес статьи (URL);
<<статья:20>> — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

Поделитесь ссылкой в социальных сетях:

Комментарии читателей к данной статье

Цитата (GolDrag):

Забыли про Insert
Insert(Text, ToText: string; Pos: integer);

Процедура вставляет строку Text в строку ToText перед позицией Pos.

Target := ‘12345678’;
Insert(‘-+-‘, Target, 3);

В результате:
Target : 12-+-345678

Оставлять комментарии к статьям могут только зарегистрированные пользователи.

Работа со строковыми типами данных в Delphi

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

Строка — это последовательность символов. В Object Pascal существует несколько строковых типов. Вот основные из них:

Для большинства целей подходит тип AnsiString (иногда называется Long String).

Стандартные функции обработки строк:

1) Функция Length(Str: String) — возвращает длину строки (количество символов). Пример:

var
Str: String; L: Integer;
< . >
Str := ‘Hello!’ ;
L := Length(Str);

2) Функция SetLength(Str: String; NewLength: Integer) позволяет изменить длину строки. Если строка содержала большее количество символов, чем задано в функции, то «лишние» символы обрезаются. Пример:

Читать еще:  Ассемблерные вставки в c visual studio

var Str: String;
< . >
Str := ‘Hello, world!’ ;
SetLength(Str, 5);

3) Функция Pos(SubStr, Str: String) — возвращает позицию подстроки в строке. Нумерация символов начинается с единицы (1). В случае отсутствия подстроки в строке возращается 0. Пример:

var Str1, Str2: String; P: Integer;
< . >
Str1 := ‘Hi! How do you do?’ ;
Str2 := ‘do’ ;
P := Pos(Str2, Str1);

4) Функция Copy(Str: String; Start, Length: Integer) — возвращает часть строки Str, начиная с символа Start длиной Length. Ограничений на Length нет — если оно превышает количество символов от Start до конца строки, то строка будет скопирована до конца. Пример:

var Str1, Str2: String;
< . >
Str1 := ‘This is a test for Copy() function.’ ;
Str2 := Copy(Str1, 11, 4);

5) Процедура Delete(Str: String; Start, Length: Integer) — удаляет из строки Str символы, начиная с позиции Start длиной Length. Пример:

var Str1: String;
< . >
Str1 := ‘Hello, world!’ ;
Delete(Str1, 6, 7);

6) Функции UpperCase(Str: String) и LowerCase(Str: String) преобразуют строку соответственно в верхний и нижний регистры:

var Str1, Str2, Str3: String;
< . >
Str1 := ‘hELLo’ ;
Str2 := UpperCase(Str1); < Str2 = "HELLO" >
Str3 := LowerCase(Str1);

Строки можно сравнивать друг с другом стандартным способом:

var Str1, Str2, Str3: String; B1, B2: Boolean;
< . >
Str1 := ‘123’ ;
Str2 := ‘456’ ;
Str3 := ‘123’ ;
B1 := (Str1 = Str2); < B1 = False >
B2 := (Str1 = Str3);

Если строки полностью идентичны, логическое выражение станет равным True.

Дополнительные функции обработки строк:

В модуле StrUtils.pas содержатся полезные функции для обработки строковых переменных. Чтобы подключить этот модуль к программе, нужно добавить его имя (StrUtils) в раздел Uses.

1) PosEx(SubStr, Str: String; Offset: Integer) — функция аналогична функции Pos(), но позволяет задать отступ от начала строки для поиска. Если значение Offset задано (оно не является обязательным), то поиск начинается с символа Offset в строке. Если Offset больше длины строки Str, то функция возратит 0. Также 0 возвращается, если подстрока не найдена в строке. Пример:

uses StrUtils;
< . >
var Str1, Str2: String; P1, P2: Integer;
< . >
Str1 := ‘Hello! How do you do?’ ;
Str2 := ‘do’ ;
P1 := PosEx(Str2, Str1, 1); < P1 = 12 >
P2 := PosEx(Str2, Str1, 15);

2) Функция AnsiReplaceStr(Str, FromText, ToText: String) — производит замену выражения FromText на выражение ToText в строке Str. Поиск осуществляется с учётом регистра символов. Следует учитывать, что функция НЕ изменяет самой строки Str, а только возвращает строку с произведёнными заменами. Пример:

uses StrUtils;
< . >
var Str1, Str2, Str3, Str4: String;
< . >
Str1 := ‘ABCabcAaBbCc’ ;
Str2 := ‘abc’ ;
Str3 := ‘123’ ;
Str4 := AnsiReplaceStr(Str1, Str2, Str3);

3) Функция AnsiReplaceText(Str, FromText, ToText: String) — выполняет то же самое действие, что и AnsiReplaceStr(), но с одним исключением — замена производится без учёта регистра. Пример:

uses StrUtils;
< . >
var Str1, Str2, Str3, Str4: String;
< . >
Str1 := ‘ABCabcAaBbCc’ ;
Str2 := ‘abc’ ;
Str3 := ‘123’ ;
Str4 := AnsiReplaceText(Str1, Str2, Str3);

4) Функция DupeString(Str: String; Count: Integer) — возвращает строку, образовавшуюся из строки Str её копированием Count раз. Пример:

uses StrUtils;
< . >
var Str1, Str2: String;
< . >
Str1 := ‘123’ ;
Str2 := DupeString(Str1, 5);

5) Функции ReverseString(Str: String) и AnsiReverseString(Str: AnsiString) — инвертируют строку, т.е. располагают её символы в обратном порядке. Пример:

uses StrUtils;
< . >
var Str1: String;
< . >
Str1 := ‘0123456789’ ;
Str1 := ReverseString(Str1);

6) Функция IfThen(Value: Boolean; ATrue, AFalse: String) — возвращает строку ATrue, если Value = True и строку AFalse если Value = False. Параметр AFalse является необязательным — в случае его отсутствия возвращается пустая строка.

uses StrUtils;
< . >
var Str1, Str2: String;
< . >
Str1 := IfThen(True, ‘Yes’ ); < Str1 = "Yes" >
Str2 := IfThen(False, ‘Yes’ , ‘No’ );

Мы рассмотрели функции, позволяющие выполнять со строками практически любые манипуляции. Как правило, вместо строки с указанным типом данных, можно использовать и другой тип — всё воспринимается одинаково. Но иногда требуются преобразования. Например, многие методы компонент требуют параметр типа PChar, получить который можно из обычного типа String функцией PChar(Str: String):

uses ShellAPI;
< . >
var FileName: String;
< . >
FileName := ‘C:WINDOWSnotepad.exe’ ;
ShellExecute(0, ‘open’ , PChar(FileName), » , » , SW_SHOWNORMAL);

Тип Char представляет собой один-единственный символ. Работать с ним можно как и со строковым типом. Для работы с символами также существует несколько функций:

Chr(Code: Byte) — возвращает символ с указанным кодом (по стандарту ASCII):

Ord(X: Ordinal) — возвращает код указанного символа, т.е. выполняет противоположное действие функции Chr():

Из строки можно получить любой её символ — следует рассматривать строку как массив. Например:

var Str, S: String; P: Char;
< . >
Str := ‘Hello!’ ;
S := Str[2]; < S = "e" >
P := Str[5];

В этой статье описаны основные приёмы работы со строковыми типами данных. Как правило, этих данных достаточно для написания любого алгоритма.

Работа со строками в Delphi 10.3 Rio

Работа со строками в Delphi — это отдельная и очень обширная тема. Рассмотреть в одной статье все тонкости и особенности строк delphi представляет собой достаточно сложную задачу сравнимую, наверное, с написанием небольшой книги, просто по причине того, что в Delphi на сегодняшний день используются разные типы строк (ShortString, AnsiString, UnicodeString и прочие) и каждый тип для чего-то да нужен — для обратной совместимости, для COM BSTR, для разработки под мобильные платформы и так далее.

Вместе с этим, Delphi постоянно развивается, что-то добавляется, что-то улучшается и вот уже те инструменты работы со строками в Delphi, которые вызывали недоумение своим появлением, например, в Delphi 2009 в Delphi 10.3 Rio начинают играть другими красками. На написание этой статьи меня подтолкнула статья « What’s New » для Delphi 10.3 Rio, а именно то, что разработчики Delphi отдельным пунктом выделили, что давным давно существующий в Delphi класс TStringBuilder оптимизирован и даже обзавелся перегруженным методом ToString использование которого может увеличить производительность. Вот я и решил проверить — на сколько же выросла производительность TStringBuilder в Delphi по сравнению с тем, что было в далеком 2008 году, когда не было ни поддержки мобильных платформ, ни x64 с Linux.

Справка по TStringBuilder

TStringBuilder — это специализированный класс для работы со строками в Delphi (аналог класса StringBuilder в .NET Framework).

TStringBuilder поддерживает выполнение таких операций со строками как конкатенация (сложение), поиск, заменена и вставка подстрок. При этом, массив символов может быть запрошен по индексу или преобразован в строку для сравнения.

На массив символов можно ссылаться напрямую, используя свойство Chars. Свойство Length содержит текущую длину массива символов.

Работать с классом TStringBuilder в Delphi достаточно просто:

Обратить внимание стоит на то, что TStringBuilder работает с 0-индексированными (0-based) строками — первый символ имеет индекс 0, а не 1, как мы привыкли в Delphi. В остальном же, работа с TStringBuilder основана на использовании следующих методов:

Append — добавить подстроку к строке (конкатенация строк). Метод перегружен поэтому, Вы можете добавлять к строке числа, массивы символов и другие типы, например так:

Insert — вставить подстроку в строку с заданной позиции (метод также перегружен)

Replace — заменить подстроку (или символ) на другую строку (символ). Заменяет все вхождения подстрок.

CopyTo — копирование части строки в строку-приемник.

В Delphi 10.3 Rio TStringBuilder обзавелся также перегруженным методом ToString:

По сообщению разработчиков Delphi, ToString (True) даст лучшую производительность, если больше не ожидается никаких изменений для TStringBuilder, поскольку это уменьшает объем копируемых данных.

Читать еще:  Поддержка ява скрипт как включить

Со всеми методами TStringBuilder можно ознакомиться в справке Delphi.

Меня же больше интересует насколько TStringBuilder стал более производительным в части конкатенации строк по сравнению с обычной (привычной, классической) операцией сложения?

Вводные для теста производительности TStringBuilder

Итак, что у меня имеется для тестирования TStringBuilder:

Стационарный компьютер имеет следующие характеристики:

  • Процессор Intel Core i5 8400 (6-ти ядерный)
  • ОЗУ: 16 ГБ
  • ОС: Windows 10 x64

Смартфон LG Q7+ (Android 8.1.0)

Класс TStrings — операции со строковыми данными в Делфи

Класс TStrings является базовым классом для операций со строковыми данными. Этот класс представляет собой контейнер для строк (коллекцию или массив строк). Для операций со строками класс TStrings предоставляет соответствующие свойства и методы. От класса TStrings происходит большое количество производных классов, например, TStringList, которые могут использоваться для задания различных типов строк.

Визуальные компоненты, способные работать со списком строк, имеют свойства, которые являются массивами строк, содержащихся в этих компонентах. Например, для списков ListBox и DBListBox и для групп зависимых переключателей RadioGroup и DBRadioGroup таким свойством является Items, а для многострочных редакторов Memo и DbMemoLines.

Указанные свойства для визуальных компонентов ListBox и Memo доступны при разработке и при выполнении приложения, а для визуальных компонентов DBListBox и DBMemo, связанных с данными, — только при выполнении приложения.

Особенности класса TStrings

Рассмотрим особенности и использование класса TStrings на примере свойства Items списков. Работа с другими объектами типа TStrings происходит аналогично.

Каждый элемент списка является строкой, к которой можно получить доступ по ее номеру в массиве строк Items. Отсчет элементов списка начинается с нуля. Для обращения к первому элементу нужно указать Items[0], ко второму— Items[1], к третьему — Items[2] и т. д. При операциях с отдельными строками программист должен контролировать номера строк в списке и не допускать обращения к несуществующему элементу. Например, если список содержит три строки, то попытка работы с десятой строкой приведет к исключению.

Свойство Count

Свойство Count типа Integer задает число элементов в списке. Поскольку первый элемент списка имеет нулевой номер, то номер последнего элемента равен Count-1.

Например, присваивание элементам списка ListBox1 новых значений может быть реализовано так:

Методы Add и Insert

Методы Add и Insert служат для добавления/вставки строк в список. Функция Add (const S: string): integer добавляет заданную параметром S строку в конец списка, а в качестве результата возвращает положение нового элемента в списке. Процедура Insert (Index: Integer; const S: String) вставляет строку S в позицию с номером, определяемым параметром index. При этом элементы списка, находившиеся до операции вставки в указанной позиции и ниже, смещаются вниз.

В приводимой далее процедуре к комбинированному списку СomboBox1 добавляется строка Нажата кнопка Button1:

Заполнение списка с помощью методов AddStrings и AddObject

Для заполнения списка можно использовать методы AddStrings и AddObject. Метод AddStrings позволяет при вызове увеличить содержимое списка более чем на один элемент.

Процедура AddStrings (strings: TStrings) добавляет в конец списка группу строк, определяемую параметром Strings. Класс TStrings позволяет хранить строки и ссылки на объектыпроизвольного типа.

Функция AddObject (const S: String; AObject: TObject): Integer добавляет в конец списка строку S и связанную с ней ссылку на объект, указываемую параметром AObject.

Рассмотрим следующий пример заполнения списка:

Здесь список TS заполняется перечнем названий страниц блокнота PageControl1 при создании формы Form1. Вместе с названиями запоминаются ссылки на страницы. Страницы блокнота имеют тип TTabSheet. Знание типа необходимо при последующей работе с задаваемыми посредством ссылок объектами, в частности, для корректного выполнения операции, такой как программное переключение страниц управляющего элемента PageControl1. Вместо переменной TS можно использовать другой список подходящего типа, например, список компонента ListBox, доступный через свойство Items.

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

Процедура Assign

Процедура Assign (Source: TPersistent) присваивает один объект другому, при этом объекты должны иметь совместимые типы. В результате выполнения процедуры информация копируется из одного списка в другой с заменой содержимого. Если размеры списков (число элементов) не совпадают, то после замены число элементов заменяемого списка становится равным числу элементов копируемого списка.

Функция Equals

Функция Equals (Strings: TStrings): Boolean используется для определения, содержат ли два списка строк одинаковый текст. Если содержимое списков совпадает, то функция возвращает значение True, в противном случае— значение False. Содержимое списков одинаково, если списки равны по длине и совпадают все их соответствующие элементы.

В приведенном далее примере производится согласование двух списков по содержанию:

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

Удаление элементов списка с помощью методов Delete и Сlear

Для удаления элементов списка используются методы Delete и Сlear. Метод Delete (index: integer) удаляет элемент с номером, заданным параметром index. При попытке удаления несуществующей строки сообщение об ошибке не выдается, но метод Delete не срабатывает.

при нажатии кнопки Button2 из комбинированного списка ComboBox1 удаляется пятая строка.

Метод Сlear очищает список, удаляя все его элементы в следующей процедуре:

при нажатии кнопки btnClearPersonalList очищается список lbPersonal.

Процедура Move

Процедура Move (Curindex, NewIndex: integer) перемещает элемент из позиции с номером CurIndex в новую позицию с номером NewIndex. Если указанный номер выходит за пределы списка, то возникает исключение.

Поиск элементов в списке процедурой IndexOf

Поиск элемента в списке можно выполнить с помощью метода IndexOf. Процедура IndexOf (const S: string): integer определяет, содержится ли строка S в списке. В случае успешного поиска процедура возвращает номер позиции найденной строки в списке; если строковый элемент не найден, то возвращается значение −1.

Работа с текстовыми файлами с помощью методов SaveToFile и LoadFromFile

У класса TStrings есть методы SaveToFile и LoadFromFile, позволяющие непосредственно работать с текстовыми файлами. Эти методы предоставляют возможность сохранения строк списка в текстовом фате на диске и последующего чтения строк из этого файла. Символы файла кодируются в системе ANSI.

Процедура SaveToFile (const FileName: String) сохраняет строковые элементы списка в файле FileName. Если заданный файл отсутствует на диске, то он создается. В последующем сохраненные строки можно извлечь из файла, используя метод LoadFromFile. Например:

Здесь содержимое списка ListBox3 записывается в файл names.txt каталога C:COMPANY.

Процедура LoadFromFile (const FileName: String) заполняет список содержимым указанного текстового файла, при этом предыдущее содержимое списка стирается. Если заданный файл отсутствует на диске, то возникает исключение.

Пример заполнения списка содержимым файла:

Файл personal.txt содержит фамилии сотрудников организации. При запуске приложения содержимое этого файла загружается в комбинированный список ComboВох2.

При конструировании приложения изменение списка строк выполняется с помощью строкового редактора String List Editor.

Его можно вызвать из окна Инспектора объектов двойным щелчком мыши в области значения свойства типа TStrings (например, в области значения свойства Items списка ListBox).

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

Один комментарий к “Класс TStrings — операции со строковыми данными в Делфи”

Строковые типы в Delphi. Особенности реализации и использования

В этой статье будут освещены следующие вопросы:

  1. Какие строковые типы существуют в Delphi, и чем они отличаются друг от друга
  2. Преобразование строк из одного типа в другой
  3. Некоторые приемы использования строк типа AnsiString:
    1. Функции для работы со строками о которых многие часто забывают или вовсе не знают
    2. Передача строк в качестве параметров
    3. Использование строк в записях
    4. Запись в файл и чтение из файла
    5. Использование строк в качестве параметров и результатов функций размещенных в DLL.
Читать еще:  Delphi экспорт базы в xml

Ну что, интересно? Тогда поехали.

Какие строковые типы существуют в Delphi, и чем они отличаются друг от друга?

В Delphi 1.0 существовал лишь единственный строковый тип String, полностью эквивалентный одноименному типу в Turbo Pascal и Borland Pascal. Однако, этот тип имеет существенные ограничения, о которых я расскажу позднее. Для обхода этих ограничений, в Delphi 2, разработчики из Borland устроили небольшую революцию. Теперь, начиная с Delphi 2, имеются три фундаментальных строковых типа: ShortString, AnsiString, и WideString. Кроме того, тип String теперь стал логическим. Т.е., в зависимости от настройки соответствующего режима компилятора (режим больших строк), он приравнивается либо к типу ShortString (для совместимости со старыми программами), либо к типу AnsiString (по умолчанию). Управлять режимом, можно используя директиву компиляции <$LONGSTRINGS ON/OFF>(короткая форма <$H+/->) или из окна настроек проекта – вкладка «Compiler» -> галочка «Huge strings». Если режим включен, то String приравнивается к AnsiString, иначе String приравнивается ShortString. Из этого правила есть исключение: если в определении типа String указан максимальный размер строки, например String[25], то, вне зависимости от режима компилятора, этот тип будет приравнен к ShortString соответствующего размера.

Поскольку, как вы узнаете в дальнейшем, типы ShortString и AnsiString имеют принципиальное отличие в реализации, то я вообще не рекомендую пользоваться логическим типом String без указания размера, если Вы, конечно, не пишете программ под Delphi 1. Если же Вы все-таки используете тип String, то я настоятельно рекомендую прямо в коде Вашего модуля указывать директиву компиляции, устанавливающую подразумеваемый Вами режим работы компилятора. Особенно если Вы используете особенности реализации соответствующего строкового типа. Если этого не сделать, то однажды, когда Ваш код попадет в руки другого программиста, не будет никакой гарантии того, что его компилятор будет настроен, так же как и Ваш.

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

Сразу же упомяну о различии между типами AnsiString и WideString. Эти типы имеют практически одинаковую реализацию, и отличаются лишь тем, что WideString используется для представления строк в кодировке UNICODE использующей 16-ти битное представление каждого символа (WideChar). Эта кодировка используется в тех случаях когда необходима возможность одновременного присутствия в одной строке символов из двух и более языков (помимо английского). Например, строк содержащих одновременно символы английского, русского и европейских языков. За эту возможность приходится платить – размер памяти, занимаемый такими строками в два раза больше размера, занимаемого обычными строками. Использование WideString встречается не часто, поэтому, я буду в основном рассказывать о строках типа AnsiString. Но, поскольку они имеют одинаковую реализацию, почти все сказанное относительно AnsiString будет действительно и для WideString, естественно с учетом разницы в размере каждого символа.

Тоже самое касается и разницы между pChar и pWideChar.

Строковый тип AnsiString, обычно используется для представления строк в кодировке ANSI, или других (например OEM) в которых для кодирования одного символа используется один байт (8 бит). Такой способ кодирования называется single-byte character set, или SBCS. Но, очень многие не знают о существовании еще одного способа кодирования многоязычных строк (помимо UNICODE) используемого в системах Windows и Linux. Этот способ называется multibyte character sets, или MBCS. При этом способе, некоторые символы представляются одним байтом, а некоторые, двумя и более. В отличие от UNICODE, строки, закодированные таким способом, требуют меньше памяти для своего хранения, но требуют более сложной обработки. Так вот, строковый тип AnsiString может использоваться для хранения таких строк. Я не буду подробно останавливаться на этом способе кодирования, поскольку он применяется крайне редко. Лично я, ни разу не встречал программ использующих данный способ кодирования.

Знатоки Delphi вероятно мне сразу напомнят еще и о типах pChar (pWideChar) и array [. ] of Char. Однако, я считаю, что это не совсем строковые типы, но я расскажу и о них, поскольку они очень часто используются в сочетании со строковыми типами.

Итак, приведу основные характеристики строковых типов:

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

Здесь, как мы уже знаем, после выполнения оператора s2 := s1, обе переменные указывают на один и тот же экземпляр строки ‘abc123’. Однако, что же произойдёт когда выполниться оператор s2[1] := ‘X’? Казалось бы, в единственном имеющимся в нашем распоряжении экземпляре строки первая буква будет заменена на ‘X’. И как следствие, обе строки станут равными ‘Xbc123’. s1 то за что «страдает»? Но, к счастью это не так. Здесь на помощь Delphi вновь приходит счетчик ссылок. Delphi, при выполнении этого оператора понимает, что строка на которую указывает s2 будет изменена, а это может повлиять на других. Поэтому, перед изменением строки, проверяется ее счётчик ссылок. Обнаружив, что на нее ссылается более одной строковой переменной, делается следующее: создается копия этой строки со счётчиком ссылок равным 1, и адрес этой копии, присваивается s2; У исходного экземпляра строки, счетчик ссылок уменьшается на 1 – ведь s2 на неё теперь не ссылается. И лишь после этого, происходит изменение первой буквы, теперь уже собственного экземпляра строки. Т.е., по окончанию выполнения этого оператора, в памяти будут находиться две строки: ‘abc123’ и ‘Xbc123’. Причем, s1 будет ссылаться на первую, а s2 на вторую.

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

Казалось бы, при завершении работы процедуры, экземпляр строки ‘Вася’ должен быть уничтожен. Но в данном случае это не так. Ведь, при следующем входе в процедуру, для выполнения присваивания нужно будет вновь где-то взять строку ‘Вася’. Для этого, ещё при компиляции, Delphi размещает экземпляр строки ‘Вася’ в области констант программы, где её даже невозможно изменить, по крайней мере, простыми методами. Но как же при завершении процедуры определить что строка ‘Вася’ – константная строка, и ее нельзя уничтожать? Все очень просто. Для константных строк, счётчик ссылок устанавливается равным -1. Это значение, «выключает» нормальный алгоритм работы со «счётчиком ссылок». Он не увеличивается при присваивании, и не уменьшается при уничтожении переменной. Однако, при попытке изменения переменной (помните s2[1]:=’X’), значение счётчика равное -1 будет всегда считаться признаком того, что на строку ссылается более одной переменной (ведь он не равен 1). Поэтому, в такой ситуации всегда будет создаваться уникальный экземпляр строки, естественно, без декремента счётчика ссылок старой. Это защитит от изменений экземпляр строки-константы.

К сожалению, этот алгоритм срабатывает не всегда. Но об этом, мы поговорим позже, при рассмотрении вопросов преобразования строковых типов.

Где же Delphi хранит «счётчик ссылок»? Причем, для каждой строки свой! Естественно, вместе с самой строкой. Вот что представляет собой эта область памяти, хранящая экземпляр строки ‘abc’:

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector