TSysCharSet — Тип Delphi

Ввод и вывод в Delphi

Читайте также:

  1. АНАЛИЗ ТЕОРЕТИКО-ЭКСПЕРИМЕНТАЛЬНЫХ ИССЛЕДОВАНИЙ И ФОРМУЛИРОВАНИЕ ВЫВОДОВ И ПРЕДЛОЖЕНИЙ
  2. Ввод и вывод данных
  3. Ввод и вывод двумерных массивов
  4. Ввод и вывод с помощью внешних файлов
  5. Ввод одномерных массивов. Вывод одномерных массивов
  6. Ввод-вывод одномерных и двухмерных массивов
  7. Ввод-вывод.
  8. Вывод данных
  9. ВЫВОД ДВУМЕРНОГО МАССИВА
  10. Вывод дифференциального уравнения Б-Ш-М
  11. Вывод закона Стокса в главной системе координат.

Классы в Delphi

Лекция 24

Delphi имеет обширный набор классов. Фрагмент структуры классов Delphi приведен на рис.5.24.1.

Предком всех классов Delphi является класс TObject. Он обладает самыми общими методами присущими любому объекту Паскаля. Этот класс описывает основные принципы поведения объектов во время работы программы (создание, уничтожение, обработка событий и так далее).

Класс TPersistent (наследник TObject) реализует основные методы копирования содержимого объектов.

Класс TComponent (наследникTPersistent) — это основной родительский класс для всех классов описывающих компоненты Delphi. Этот класс содержит набор общих свойств (число объектов подчиненных данному; список объектов, подчиненных данному, текущее состояние компонента и т.п.) и общих методов (добавление объекта в список компонентов; удаление объекта из списка компонентов и т.д.).

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

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

— создавать надписи на самой форме;

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

.5.12.1. Компонент Label (класс TLabel)

Пиктограмма: .

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

Замечание. Общий заголовок для формы оформляется путем размещения текста заголовка в свойстве Caption формы. Этот заголовок будет размещаться на верхней полоске формы.

Пример. Пусть в форме мы хотим сделать заголовок «Решение уравнения».

Для создания такого текста надо:

1. В палитре компонентов выбрать страницу «Стандартные»;

2.В палитре компонентов со страницы «Стандартные»; выбрать кнопку с буквой А, щелкнуть по этой кнопке левой кнопкой мыши и нарисовать прямоугольник в нужном месте формы. В результате в форме появится выделенный прямоугольник с надписью «Label1».

Если посмотреть текст модуля формы, то в нем в описании класса формы появится текст

3. В Инспекторе объектов активизируем вкладку свойств компонента Label1 и в свойстве Caption запишем «Решение уравнения». Можно заметить, что сразу же этот текст появится и в форме.

Наглядный вид и характеристики этого компонента можно изменять задавая различные значения свойствам компонента (полезно поэкспериментировать), например:

— свойство Color позволяет изменить цвет фона;

— свойство Font позволяет задавать различные цвет, размер и шрифт символов (для открытия диалогового окна надо щелкнуть по кнопке с тремя точками);

— если свойство Autosize имеет значение True, то размеры прямоугольника будут автоматически устанавливаться в соответствии с размером текста;

n если для свойства WordWrap установить значение True, то текст будет располагаться на нескольких строках — горизонтальный размер окна будет зафиксирован, по мере ввода текста будет изменяться вертикальный размер окна.

Для вывода текста в процессе выполнения программы надо просто присвоить имени поля значение строки символов (переменной или константы)

Label1.Caption:= S; , где S- переменная строкового типа.

5.12.2. Компонент Edit (класс Tedit).

Это прямоугольное окно, в котором возможны ввод и редактирование текста. Можно: вводить, выводить, выделять, копировать, удалять текст.

Компонент Edit — это однострочный редактор, т.е. на экране отображается только одна строка. Записывать в Edit символы можно как со стороны пользователя, так и со стороны программы, т.е. строку Edit можно использовать как для ввода данных в программу, так и для вывода результатов из программы. В форме можно разместить несколько компонент EDIT, все они будут иметь оригинальные имена: Edit1, Edit2, и так далее. Значение вводимой строки присваивается свойству Text этого компонента.

Свойства компонента Edit.

Кроме типичного набора свойств -, Name, Enabled, Top, Height и т.п. этот компонент обладает следующими свойствами.

ReadOnly — это свойство позволяет запретить (значение True) ввод и редактирование текста со стороны пользователя.

TabOrder — задает порядок получения компонентом фокуса при нажатии клавиши Tab. По умолчанию этот порядок определяется порядком размещения компонентов в форме. Компонент с номером 0 получает фокус при открытии формы. Это свойство можно использовать только совместно со свойством TabStop.

TabStop — это свойство позволяет указать может ли компонент получать фокус (значение True) или нет.

Text — это свойство предназначено для записи в строку Edit значения вводимой строки и для чтения из строки последовательности символов. По умолчанию в этом свойстве записано EditX (X — номер компонента Edit в форме).

MaxLength — определяет максимальную длину текста строки в символах. Если значение этого свойства равно 0, то ограничений на длину текста нет.

Свойство AutoSize в окнах редактирования имеет смысл, отличный от смысла аналогичного свойства меток: автоматически подстраивается под размер текста только высота, но не ширина окна.

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

Ctrl-C — копирование выделенного текста в буфер обмена Clipboard (команда Copy),

Ctrl-X — вырезание выделенного текста в буфер Clipboard (команда Cut), Ctrl-V — вставка текста из буфера Clipboard в позицию курсора (команда Paste),

Ctrl-Z — отмена последней команды редактирования.

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

Свойство PasswordChar позволяет превращать окно редактирования в окно ввода пароля. По умолчанию значение PasswordChar равно #0 — нулевому символу. В этом случае это обычное окно редактирования. Но если в свойстве указать иной символ (например, символ звездочки «*»), то при вводе пользователем текста в окне будут появляться именно эти символы, а не те, которые вводит пользователь. Тем самым обеспечивается секретность ввода пароля.

При создании строки редактирования автоматически создается переменная типа String, общая форма имени которой имеет вид

имя_поля.text;.

Например, если в окно с именем Edit3 ввести последовательность символов ‘ABC’, то переменная Edit3.text получит значение ‘ABC’. Это значение можно присвоить любой переменной типа string, например

var S: String;

Для записи последовательности символов из программы в строку Edit1 достаточно выполнить оператор присваивания

Edit1.Text := St; (St — переменная строкового типа).

Пример. Для иллюстрации ввода и вывода данных с помощью компонента Edit создадим проект с формой, показанной на рис.5.24.1

Рис. 5.24.1 Форма для примера

То есть форма должна содержать строку Edit и две кнопки: «закрыть» и «операция». В строку Edit будем записывать символы. При нажатии на кнопку «операция» программа должна забирать введенную последовательность символов, делать с ней некоторые преобразования (например, добавлять слева и справа символ #) и возвращать результат в строку Edit.

1.Создадим форму с заголовком «пример», для этого запишем в свойстве Caption формы слово «пример».

2.Создадим две кнопки «закрыть» и «операция». Как создать кнопки мы уже рассмотрели. Заметим только — при создании второй кнопки в описание класса будет добавлен компонент

и метод для обработки события связанного со второй кнопкой

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

2. Создадим строку редактирования Edit. Для этого

— в палитре компонентов выберем страницу «стандартные»;

— щелкнем по кнопке и нарисуем в форме прямоугольник.

На экране в форме появится выделенный прямоугольник с текстом Edit1.

Значение строки редактирования передается через свойство Text, по умолчанию в этом свойстве записано Edit1. Удалим этот текст из свойства Text.

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

5.12.3. Ввод и вывод символьных данных.

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

— взять строку символов и добавить слева и справа символ # ;

— удалить из строки исходную последовательность;

— вывести в строку Edit полученную последовательность.

Для реализации этих функций необходимо в модуле формы добавить следующее (выделено жирным шрифтом):

a) в разделе переменных указать переменную (например S) строкового типа, т.е. раздел переменных будет иметь вид

S : String;

б) в процедуру обработчика события для кнопки «операция» добавить текст:

procedure Tform1.Button2Click(sender: Tobject);

S:=Edit1.Text; //чтение из окна в S

Edit1.Text := »; //очистка окна

S:= ‘#’ + S + ‘#’; //добавление символов слева и справа

Edit1.Text := S; //запись в окно новой строки

Полный текст модуля формы приведен ниже.

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type TForm1 = class(TForm)

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

var Form1: TForm1;

procedure TForm1.Button1Click(Sender: TObject);

procedure TForm1.Button2Click(Sender: TObject);

5.12.4. Ввод и вывод чисел.

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

Val(S,m,n) — для преобразования последовательности символов (S) в число (m). Если число содержит недопустимый символ, то переменная n (целого типа) получает значение кода этого символа.

Пример: если в поле Edit1 мы ввели число, значение которого должна получить переменная А, то надо записать

(переменная cod должна быть объявлена как данное целого типа);

Str(Y,S) — для преобразования числа (У) в последовательность символов (S) (символьное изображение числа). В функции Str можно также указывать ширину поля (Sp) и количество десятичных знаков (dz) как и в процедуре write, т.е. форма записи функции Str имеет вид

Например, запись вида Str(y:7:3,S1);

означает, что символьное представление числа У будет занимать поле из 7 позиций и в дробной части числа будет 3 позиции, а переменная Z будет представлена в форме с буквой Е и мантисса будет содержать пять цифр в дробной части, например

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

FloatToStr(X) — преобразует вещественное число типа Extended в символьное представление.

IntToStr(N) — преобразует целое число типа Integer в строку символов.

StrToFloat(s) — преобразует строку s в двоичное вещественное число типа Extended.

StrToInt(s) — преобразует строку s в двоичное целое число типа Integer.

Пример. Преобразуем предыдущий пример так, чтобы при нажатии на кнопку «операция» программа:

— брала из поля Edit символьное представление числа;

— преобразовывала его в числовую форму (переменная Х);

— возводила в квадрат (Y:=X*X);

— полученный результат (У) преобразовывала в символьное представление и выводила его в окне Edit.

Для этого добавим в модуль формы следующее:

1) В раздел переменных добавим описание переменных X, Y и cod, т.е.

S :String;

X,Y :Real;

cod :Integer;

2) В обработчике события для кнопки «операция» запишем

Val(Edit1.Text,X,cod);

Edit1.Text:=»;

Y:=X*X;

Str(Y,S);

Edit1.Text:=S

Полный текст модуля формы для этого примера приведен ниже.

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type TForm1 = class(TForm)

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

var Form1: TForm1;

procedure TForm1.Button1Click(Sender: TObject);

procedure TForm1.Button2Click(Sender: TObject);

| следующая лекция ==>
Свойства компонентов | Свойства компонента StringGrid

Дата добавления: 2014-01-04 ; Просмотров: 7792 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

TSysCharSet — Тип Delphi

в массив a[1]=»1″; a[2]=»2″; a[3]=»tri»; a[4]=»text»; ? В перле и php есть и это очень удобно. Также есть функции чтобы собирать массив в одну строку. В Дельфи не нашёл. Подскажите пожалуйста, или может у кого есть текст таких функций ?

—————
Есть ли в Дельфи фунции чтобы преобразовать строку «1,2,tri,text» в массив a[1]=»1″; a[2]=»2″; a[3]=»tri»; a[4]=»text»; ? В перле и php есть и это очень удобно. Также есть функции чтобы собирать массив в одну строку. В Дельфи не нашёл. Подскажите пожалуйста, или может у кого есть текст таких функций ?

RxLib, модуль RxStrUtils функции ExtractWord, WordCount и т.д.

procedure TForm1.Button8Click(Sender: TObject);
Var
Result : String;
k : integer;
begin
with TStringList.Create do
try
CommaText :=»1,2,tri,text»;
for k := 0 to Count-1 do Strings[k] := Format(«a[%d]:=»%s»»,[k+1,Strings[k]]);
ShowMessage(Text);
finally
Free;
end;
end;

With TStringList.Create Do
try
Text:=»1,2,tri,text»;
Text:=StringReplace(Text,»,»,#13#10,[rfReplaceAll]);
For t:=0 to Count-1 Do a[t]:=Strings[t];
finally
Free;
end;

>Song © (17.09.02 09:03)
А я, кажись, загнался :)

>Alx2 © (17.09.02 09:11)
>А я, кажись, загнался :)

По моему, не очень :-). Ведь достаточно StringList.CommaText:=»1,2,tri,text»;

>Song © (17.09.02 09:03)
>автору
И использовать не некий a[i], а StringList.Strings[i]

2Alx2 © (17.09.02 09:11)
Да нет, на загнался. Просто я предложил ещё один способ.

2ЮЮ © (17.09.02 09:20)
По условию задачи нужно было получить массив a[]. Что я и сделал :-))

>По условию задачи нужно было получить массив a[].
>Что я и сделал :-))
А я невнимательно пялился на вопрос и понял, что нужно получить строки типа как в Alx2 © (17.09.02 07:18)

procedure CommaSeperatedToStringList(AList: TStrings; const Value: string);

List to store the values.

const Value: string

String containing comma-delimited values.

CommaSeperatedToStringList is a procedure used to fill the TStringList AList parameter with the values from the Value parameter.
AList is cleared prior to adding values in the procedure.
Value is a comma-delimited list of values to loaded in the TStringList. Value can contain items that include the comma separator by using double quotation marks to enclosed the item. For example:

«Item One, «Item Two, with comma», Item Three»

function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer;

Use ExtractStrings to fill a string list with the substrings of the null-terminated string specified by Content.

Separators is a set of characters that are used as delimiters, separating the substrings. Carriage returns, newline characters, and quote characters (single or double) are always treated as separators. Separators are ignored when inside a quoted string until the final end quote. (Note that quoted characters can appear in a quoted string if the quote character is doubled.)

WhiteSpace is a set of characters to be ignored when parsing Content if they occur at the beginning of a string.

Content is the null-terminated string to parse into substrings.

Strings is a string list to which all substrings parsed from Content are added. The string list is not cleared by ExtractStrings, so any strings already in the string list are preserved.

ExtractStrings returns the number of strings added to the Strings parameter.

Note: ExtractStrings does not add empty strings to the list.

function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer;

Use ExtractStrings to fill a string list with the substrings of the null-terminated string specified by Content.

Separators is a set of characters that are used as delimiters, separating the substrings. Carriage returns, newline characters, and quote characters (single or double) are always treated as separators. Separators are ignored when inside a quoted string until the final end quote. (Note that quoted characters can appear in a quoted string if the quote character is doubled.)

WhiteSpace is a set of characters to be ignored when parsing Content if they occur at the beginning of a string.

Content is the null-terminated string to parse into substrings.

Strings is a string list to which all substrings parsed from Content are added. The string list is not cleared by ExtractStrings, so any strings already in the string list are preserved.

ExtractStrings returns the number of strings added to the Strings parameter.

Note: ExtractStrings does not add empty strings to the list.

2 Сергей01
Вам прийдется написать свою ф-цию.
Перед этим обязательно посмотрите исходники Делфи ф-ций работы со строками.

Могу подсказать только одно: есть класс TStringList (потомок TStrings), у этого класса есть масса полезных свойств для работы с массивами строк. И нечего гонки тут устраивать. Каждый гонит, а чего и сам не знает. Вот пример:

var
StrLst : TStringList;
S : String;
begin
StrLst := TStringList.Create;
. // заполнение массива строк значениями
S := StrLst.CommaText; // разделитель «;»
StrLst.Delimiter := #9;
S := StrLst.DelimitedText; // разделитель «Tab»
StrLst.Delimiter := #13;
S := StrLst.DelimitedText; // разделитель «Enter» (перенос строки)
StrLst.Clear;
StrLst.Free;
end;

Вот и все ваши проблемы. Только чего орать и разоряться, если не знаешь. Я считаю так: незнаешь — промолчи!

>Zemal © (17.09.02 11:55)
>Только чего орать и разоряться, если не знаешь. Я считаю >так: незнаешь — промолчи!

Извини, пожалуйста. Я обязательно научусь разбивать строки (или как это правильно называется?). Просто мне хотелось немножко порисоватся и совсем забыл, что на форуме надо быть вежливым и не кичиться тем, чего не знаешь (да и чем знаешь — тоже) и вообще не принято рисоваться. Еще раз приношу свои извинения всем, кому намозолил глаза своими выскакиваниями.

cut from Delphi help:

The following example uses a variant open array parameter in a function that creates a string representation of each element passed to it and concatenates the results into a single string. The string-handling routines called in this function are defined in SysUtils.

function MakeStr(const Args: array of const): string;

const
BoolChars: array[Boolean] of Char = («F», «T»);
var
I: Integer;
begin
Result := «»;
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger: Result := Result + IntToStr(VInteger);
vtBoolean: Result := Result + BoolChars[VBoolean];
vtChar: Result := Result + VChar;
vtExtended: Result := Result + FloatToStr(VExtended^);

vtString: Result := Result + VString^;
vtPChar: Result := Result + VPChar;
vtObject: Result := Result + VObject.ClassName;
vt >vtAnsiString: Result := Result + string(VAnsiString);
vtCurrency: Result := Result + CurrToStr(VCurrency^);
vtVariant: Result := Result + string(VVariant^);
vtInt64: Result := Result + IntToStr(VInt64^);

We can call this function using an open array constructor (see Open array constructors). For example,

MakeStr([«test», 100, » «, True, 3.14159, TForm])

returns the string “test100 T3.14159TForm”.

TSysCharSet — Тип Delphi

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

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

Место описания данных в программе — вне логических блоков begin / end. В модуле перед ключевым словом implementation есть блок описания:

Именно здесь, начиная со следующей строки, удобно объявлять глобальные переменные и константы. Как видим, одна (Form1) уже есть!

Илон Маск рекомендует:  Что такое код setenvironment

Команда объявления переменных в языке Delphi:

var имя_переменной : тип_переменной ;

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

Если несколько описаний следуют друг за другом, то ключевое слово var повторно можно не указывать:

Постоянную величину иначе называют константой. Конечно, в программе можно использовать числа и строки непосредственно: 3.1415 или ‘Это значение числа пи’ , но иногда удобнее присвоить их идентификатору. Описание констант аналогично описанию переменных, но используется ключевое слово const, за именем идентификатора следует тип, затем знак равенства и его значение. Причём тип константы допускается не указывать:

const pi= 3.1415 ;
ZnakPi : String = ‘Это значение числа пи’ ;

К слову, константа Pi встроенная в Delphi, то есть для того чтобы использовать в Delphi число 3,1415. в расчётах, нужно просто присвоить встроенную константу Pi переменной типа Real или просто использовать непосредственно в выражениях.

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

Строкой называется последовательность символов, заключённая в одиночные кавычки:
‘это текстовая строка’ Если текст должен содержать сам символ кавычки, то его надо повторить дважды:
‘это » — символ одиночной кавычки’ Строка может быть и пустой, не содержащей символов. Тогда она состоит из двух идущих друг за другом без пробела кавычек. Естественно, строка может состоять и только из одних пробелов.
Самый популярный строковый тип — String. Строка типа String может содержать переменное количество символов объёмом до 2 Гбайт. Если нужно ограничить размер строки фиксированным значением, то после ключевого слова String в квадратных скобках указывается число, определяющее количество символов в строке: String[50]. Более полно работа со строками Delphi описывается далее.
Одиночный символ имеет тип Char и записывается в виде знака в одиночных кавычках: ‘a’. Есть символы, которые на экране отобразить невозможно, например, символ конца строки (равен #13), символ переноса строки (равен #10). Такие символы записываются в виде их числового кода (в кодировке ANSI), перед которым стоит знак #. Например, #0.
Наконец, существуют так называемые нуль-терминированные строки. Отсчёт символов в таких строках начинается с нуля, а заканчивается символом с кодом (#0). Такие строки имеют тип PChar.

Числа бывают целые и дробные.
В следующей таблице перечислены стандартные типы целых чисел и соответствующие им дипазоны допустимых значений.

Integer -2147483648 .. +2147483647
Cardinal 0 .. 4294967295
Shortint -128 .. +127
Smallint -32768 .. +32767
Int64 -2 63 .. +2 63 -1
Byte 0 .. +255
Word 0 .. +65535
Наиболее удобным для использования в программах является тип Delphi Integer. Другие целые типы используются для уменьшения места, занимаемого данными в памяти компьютера.

Дробные числа имеют дробную часть, отделяемую десятичной точкой. Допускается использование символа e (или E), за которым следует число, указывающее, что левую часть нужно умножить на 10 в соответствующей степени: 5e25 — пять умножить на десять в двадцать пятой степени.
Ниже приведены стандартные типы дробных чисел и соответствующие им диапазоны допустимых значений. Для большинства типов указан диапазон положительных значений, однако допустимым является аналогичный диапазон отрицательных значений, а также число .

Real 5*10 -324 .. 1.7*10 308
Real48 2.9*10 -39 .. 1.7*10 38
Singl 1.5*10 -45 .. 3.4*10 38
Double 5*10 -324 .. 1.7*10 308
Extended 3.6*10 -4951 .. 1.1*10 4932 -1
Comp -2 63 .. +2 63 -1
Currency 922337203685477.5807
Наиболее удобным для использования в программах является тип Delphi Real. Ему эквивилентен тип Double, но в будущем это может быть изменено. Вычисления с дробными числами выполняются приближённо, за исключением типа Currency (финансовый), который предназначен для минимизации ошибок округления в бухгалтерских расчётах.

Следующим типом данных является логический Boolean, состоящий всего из двух значений: True (Истина) и False (Ложь). При этом True > False.

Теперь, используя компоненты, их свойства и события, вводя собственные переменные, можно конструировать программы, содержащие вычисления. Осталось узнать, как вычисленное значение вывести на экран.
Про консольные программы я здесь не говорю! А в нормальных оконных Windows-приложениях это значение нужно поместить в какой-нибудь компонент, имеющий свойства Text или Caption. Это, например, такие компоненты как Label и Edit, да и сама Форма имеет свойство Caption, куда тоже можно выводить информацию. Однако, в Delphi информацию перед выводом, как правило, необходимо преобразовывать. Так как присвоение возможно только между переменными одного типа, то такая программа (не пытайтесь её исполнять):

var A, B, C: Integer ;
begin
A := 5 ;
B := 10 ;
C := A+B ;
Label1.Caption := C ;
end ;

вызовет ошибку, так как свойство Caption имеет текстовый тип String, а использованные переменные — цифровой тип Integer. Значит, нужно преобразовать значение переменной C в текстовый тип. Для этого есть встроенная функция IntToStr. Строка в нашей «программе», вызывавшая ошибку, должна выглядеть так:

Такая программа, кроме показа числа 15, ни на что не способна. Мы должны научиться вводить в программу другие числа. Используем компоненты Edit. Введённые числа будут содержаться в свойстве Text этих компонентов. Расположим на форме два компонента Edit, один компонент Label и кнопку Button, по нажатию на которую и будем проводить вычисления. В компоненты Edit1 и Edit2 будем вводить числа для суммирования. Чтобы переместиться в редактор кода, щёлкнем дважды по нашей кнопке Button1. Мы попадём прямо в сформированную для нас средой Delphi заготовку обработчика нажатия на кнопку, непосредственно между операторами begin и end. Напишем такой простой код:

procedure TForm1.Button1Click(Sender: TObject);
var A, B, C: Integer; //Не забудьте описание переменных
begin
//Начало кода:
A := Edit1.Text;
B := Edit2.Text;
C := A+B;
Label1.Caption := IntToStr(C);
//Конец кода
end ;

При попытке исполнить этот код Delphi покажет ошибки по аналогичной причине — переменные A и B имеют цифровой тип Integer, а свойство Text — текстовый тип String. Исправить ошибки поможет встроенная функция StrToInt, выполняющая обратное преобразование — текст в целое число. Операторы присвоения переменным A и B должны выглядеть так:

A := StrToInt(Edit1.Text);
B := StrToInt(Edit2.Text);

В данном случае переменные A, B, C использовались для наглядности. Можно обойтись одной строчкой:

Аналогично, имеются функции и для преобразования в строку и обратно действительных чисел c плавающей (Floating англ.) запятой, имеющих тип Real. Для преобразования в строку — FloatToStr, обратно — StrToFloat.
Часто результаты вычислений, имеющие тип Delphi Real, имеют после запятой длинный «хвост» цифр. При выводе такой переменной в текстовом виде необходимо ограничить количество цифр после запятой. Как это можно сделать, описывается также в Уроке Delphi Работа со строками Delphi.

Блог GunSmoker-а (переводы)

. when altering one’s mind becomes as easy as programming a computer, what does it mean to be human.

четверг, 3 сентября 2009 г.

PChars: сами строки не включены

The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information. — Alan Perlis

В общедоступных newsgroup-ах на сервере Embarcadero я часто вижу, что по-прежнему есть много проблем с пониманием как типа PChar , так и типа String . В этой статье я хотел бы обсудить общие моменты и различия между обоими типами, а также вещи, которые вы можете и которые вы не должны делать с ними.

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

Содержание

PChar

Trying to outsmart a compiler defeats much of the purpose of using one. — Kernighan and Plauger, The Elements of Programming Style .

Идея типа PChar взята из строк языка C. Большинство функций Windows API имеют интерфейс в стиле C и принимают строки в стиле C. Чтобы можно было использовать эти API функции, Borland пришлось ввести тип, который бы подражал им, ещё в предшественнике Delphi: Turbo Pascal-е.

В C на самом деле не существует специального типа для строк, как это имеет место в Delphi. Строки в C – это просто массивы символов, а конец текста отмечается символом, ASCII код которого равен 0 . Это позволяет строкам быть большими (по сравнению со строками в Turbo Pascal-ле, где они были ограничены 255 символами из-за счётчика длины в виде байта – теперь это тип ShortString в Delphi), но несколько неудобными в использовании. Начало массива просто отмечается указателем на символ, который и стал определением типа в PChar в Delphi. Чтобы пройтись по строке в C, вы должны использовать этот указатель, как указатель на массив символов (вообще, это общее правило для всех указателей в C), и использовать s[20] для указания 21 -го символа (отсчёт начинается с 0 ). Но арифметика указателей в C позволяет делать не только инкременты и декременты, но также допускает сложение указателя с числом или вычисление разницы между двумя указателями. В C, *(s + 20) эквивалентно s[20] ( * в C является оператором разыменования, это аналог ^ в Delphi). Для типа PChar Borland сделала возможным практически тот же самый синтаксис.

Итак, PChar – это просто указатель, ровно как в C. И, снова как и в C, вы можете использовать его, как если бы это был массив (т.е. указатель, указывающий на первый элемент массива). Но на самом деле он им не является! Тип PChar не имеет автоматически управляемого хранилища данных, как это есть у обычных строк в Delphi. Если вы копируете текст в PChar -«строку», вы должны всегда быть уверенными, что этот ваш PChar действительно указывает на допустимый массив символов, и что массив достаточно велик, чтобы вместить весь текст.
Код выше не выделяет никакого хранилища для строки, поэтому он пытается сохранить символы в какое-то случайное место в памяти (адрес S неопределён и содержит какой-то мусор, см. мою статью про указатели). Это вызовет проблемы или даже вылет программы. Это ваша ответственность за гарантию наличия массива (прим. пер.: для типа String в Delphi ответственность за хранилище лежит на библиотеке поддержки языка Delphi). Простейший способ сделать это – использовать локальный массив: Код выше записывает символы в массив. Но если вы попробуете показать строку S на экране, вы, вероятно, увидите много другого мусора или даже вылет программы (*). Это потому что мы не завершили нашу строку символом #0 . OK, тогда мы можем добавить ещё одну строку: и тогда при выводе S вы получите текст » D6 «. Но записывать символы по-одному – это весьма неудобно. Чтобы показать текст через PChar , можно поступить проще: вы просто указываете PChar -ом на уже готовый массив символов с текстом в нём. К счастью, строковые константы типа ‘Delphi’ также являются такими массивами, поэтому они могут быть использованы как PChar : Вам только следует понимать, что код выше просто меняет указатель S . Сам текст никуда не копируется и не перемещается. Текст строковых констант хранится где-то в программе (и имеет терминатор #0 ), а S теперь указывает на его начало – вот и всё. Если вы сделаете: это не скопирует текст ‘Delphi’ в массив A . Первая строка после begin нацеливает указатель S на массив A , но тут же мы, во второй строке, изменяем S так, что он теперь указывает на строковую константу. Если вы хотите скопировать текст в массив, вам нужно указать это явно, используя, например, StrCopy или StrLCopy : или В конкретно этом случае нам очевидно, что строка ‘Delphi’ влезет в массив ( 101 символ как-никак), так что использование StrLCopy выглядит немного перебором, но в других случаях, когда вы не знаете наперёд размера строки, вы должны использовать StrLCopy для избежания переполнения буфера (да, ТОГО самого переполнения буфера – прим.пер.).

Массив типа A полезен как буфер для небольших строк или строк, ограниченных сверху (т.е. для которых известен максимальный потенциальный размер), но часто у вас будут строки, размер которых вам неизвестен во время компиляции. В этом случае вам нужно использовать динамическое выделение буфера для текста. Вы можете использовать, например, StrAlloc или StrNew для создания буфера, или же GetMem (а также динамические массивы или даже строки – прим.пер.), но тогда вы должны не забывать освобождать память, когда она вам станет не нужна, используя StrDispose или FreeMem . Вы также можете использовать тип String в Delphi в качестве буфера, но, прежде чем я опишу, как это сделать, я бы сперва хотел обсудить этот тип.

String

A world without string is chaos — Randolf Smuntz, Mouse Hunt

Позвольте мне вас запутать: String или, более точно, AnsiString (в Delphi 2009 и выше: UnicodeString ) фактически является PChar -ом. Точно так же, как и PChar , строка представляет собой указатель на массив символов, заканчивающихся символом #0 . Но есть одно большое отличие: обычно вам не нужно думать, как работают строки. Их можно использовать не задумываясь, почти как любую другую переменную. Компилятор сам заботится о вызове кода для выделения, копирования и освобождения текста строк. Поэтому вместо ручного вызова подпрограмм типа StrCopy , вы просто позволяете компилятору сделать это за вас.

Но это ещё не всё. Хотя текст, несомненно, всегда заканчивается символом #0 – сделано это только для того, чтобы сделать строки Delphi совместимыми со строками C, сам компилятор не нуждается в терминаторе. Перед текстом строки в памяти, по отрицательному смещению указателя, хранится длина строки, как число Integer . Так что, чтобы узнать длину строки, компилятор просто читает этот Integer , экономя на поиске первого #0 в строке. Это означает, что вы можете хранить и сам символ #0 в середине строки, и это будет работать. Но некоторые подпрограммы, которые работают с терминатором, воспримут только часть строки.

Обычно, каждый раз, когда вы присваиваете одну строку другой, компилятору надо бы выделять память и копировать текст из одной переменной в другую. Поскольку строки в Delphi могут быть очень большими (теоретически до 2 Гб максимум в 32 -х разрядных приложениях), это может быть весьма медленно. Чтобы избежать лишнего копирования, Delphi использует концепцию, которая известна под названием «копирование по требованию» («copy on demand»). Каждая строка имеет, помимо длины, и другое служебное поле: счётчик ссылок (reference count). Он содержит количество строковых переменных, которые ссылаются на конкретно эту строку в памяти. Если счётчик опускается до 0 , то это значит, что на текст строки никто больше не ссылается, и он может быть удалён из памяти.

Компилятор гарантирует вам, что счётчик ссылок всегда будет содержать правильное значение (но вы можете и обмануть компилятор: приведениями типов – подробнее об этом ниже). Если строка объявлена в секции var или как поле класса или записи, она начнёт свою жизнь как nil – внутреннее представление пустой строки ( » ). Когда текст строки только создаётся и присваивается переменной, счётчик ссылок становится равным 1 . Каждое дополнительное присваивание этой строки другой переменной будет увеличивать счётчик ссылок (никаких данных при этом не копируется). Если строковая переменная покидает область видимости (когда заканчивается функция или удаляется объект), или же ей присваивают другую строку, то счётчик ссылок уменьшается.

Простой пример: Теперь S1 указывает на текст ‘123456’ и имеет счётчик ссылок равный 1 . Текст не копируется, S2 просто указывает на тот же адрес, что и S1 , но только счётчик ссылок текста ‘123456’ теперь равен 2 . Теперь выделяется новый, больший буфер, в него копируется текст ‘The number is ‘ и туда же добавляется текст ‘123456’ . Но т.к. S2 более не указывает на текст ‘123456’ , то счётчик ссылок этого текста снова уменьшается до 1 . Result теперь указывает на тот же адрес, что и S2 , а счётчик ссылок текста ‘The number is 123456’ увеличивается до 2 . Теперь S1 и S2 выходят из области видимости. Счётчик ссылок текста ‘123456’ будет уменьшен до 0 , поэтому буфер этого текста освобождается (**). Счётчик ссылок текста ‘The number is 123456’ также уменьшается на единицу, становясь равным 1 . Сам буфер не удаляется, поскольку счётчик ссылок не равен 0 (у нас на него ещё указывает Result ).

Сложно? Да, весьма запутанно. И это становится ещё более запутанным с введением в игру var , const и out параметров. Но, к счастью, обычно вам не нужно заморачиваться этими вопросами. Такие вещи важно понимать только если вы обращаетесь к строкам из ассемблера, напрямую через PChar или с помощью подпрограмм прямого доступа к памяти. Но использование строк с приведением к PChar не является чем-то необычным. Тем не менее, если вы хотите заглянуть чуть дальше под капот языка — вы можете прочитать эту статью.

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

  • что текст копируется в новый буфер только при изменении строки;
  • что счётчик ссылок и длина текста не привязаны к строковой переменной, а только к конкретному тексту, на который могут указывать несколько (равноправных) строковых переменных;
  • что счётчик ссылок всегда верен, если только вы не наврёте компилятору, используя приведения типов;
  • что присваивание чего-то строковой переменной уменьшит счётчик ссылок текстового буфера, на который она указывала до присваивания;
  • что, если счётчик ссылок опускается до 0 , то строковый буфер удаляется.

Использования вместе String и PChar

If you can’t be a good example, then you’ll just have to be a horrible warning. — Catherine Aird

PChar и символьные массивы довольно тяжело использовать. В большинстве случаев вы должны выделять память и не забывать её освобождать. Если вы хотите добавить текст, то вы должны сперва посчитать длину получающейся строки, затем увеличить буфер, если он слишком мал, и использовать StrCat или StrLCat , чтобы, наконец, добавить текст. Вы должны использовать StrComp или StrLComp для сравнения строк и т.д. и т.п.

Строки ( String ), с другой стороны, намного проще использовать. Большинство вещей выполняется автоматически, само собой. Но множество API функций Windows (или Linux) требуют нуль-терминированных строк PChar , а не строк Delphi String . К счастью, тип String специально устроен так, что они фактически тоже являются указателями на строки, завершающиеся нулём (этот терминатор никак не используется Delphi и компилятор постоянно таскает его со строками только на этот случай). Так что любую строку String вы можете использовать и как PChar – просто приводя тип: Не забывайте, что переменная AnsiString является указателем на текст, а не самим текстовым буфером. Если текст изменяется, то он будет скопирован в другое место, а адрес в переменной соответствующим образом изменится. Это означает, что вы не должны использовать PChar для указания на строки, а затем изменять строку. Лучше всего избегать таких вещей: Если S изменяется на ‘Something else’ , указатель P не будет изменён и будет продолжать указывать на ‘C:\Test.exe’ . Поскольку P не является строковой (в смысле String ) ссылкой на этот текст, и у нас нет никакой другой переменной, ссылающейся на него, то его счётчик ссылок станет равным 0 , и текст будет удалён из памяти. Это означает, что P теперь указывает на недоступную память (invalid memory).

Будет мудрым решением не путать компилятор смешением переменных PChar и String , только если вы точно не знаете, что вы делаете. Компилятор не воспринимает PChar как String , поэтому он не будет менять счётчик ссылок строковых буферов, если вы нацелите на них PChar . Часто наилучшим решением будет отказ от подобного использования PChar . Просто используйте обычные строки, и делайте приведение типов только в последний момент. Функции, принимающие параметр PChar , должны копировать текст параметра в свои собственные переменные.

Илон Маск рекомендует:  Псевдокласс optional в CSS

Обычно строковые буферы имеют размер достаточный только для того, чтобы вместить лежащий в них (присвоенный им) текст. Но используя SetLength , вы можете установить произвольный размер строки (в символах). Это делает строки полезными для использования в качестве буферов. Например, вызов функции Windows API, которая возвращает текст в символьном массиве, может выглядеть так: Альтернативно, вы можете присвоить PChar -у String , и в результате у вас получится новая строка с копией текста. Поэтому вы можете установить длину строки с помощью такого эквивалентного кода: Последняя строка в функции устанавливает размер строки равный размеру нуль-терминированной C-строке, записанной в ней (длина C-строки всегда меньше или равна длине её String -хранилища – прим.пер.). Если вам нужен результат как PChar -строка для дальнейших действий (например для передачи в другие API-функции), вы могли бы попробовать использовать такой код: Однако, это не будет работать. Потому что Buffer является локальной переменной, хранящейся целиком в локальной памяти (процессорном стеке). Как только вы покидаете эту функцию, память, которая была выделена под Buffer , начинает использоваться другими подпрограммами, так что текст, который лежал в буфере, становится мусором. Вы никогда не должны использовать локальные переменные для возвращаемых значений PChar .

Вы могли бы обойти это, делая динамическое выделения памяти для возвращаемого PChar , с помощью, например, StrAlloc , но тогда вызывающему пришлось бы руками освобождать выделенный вами буфер. Обычно, это не самый лучший подход. Лучше следовать примеру GetWindowsDirectory , и позволить вызывающему указать свой буфер и его размер. Тогда вы просто заполните уже готовый буфер (используя StrLCopy ) своими данными до допустимого размера.

Есть и альтернативная реализация функции WindowsDirectory , которая может использовать локальный буфер. Она основывается на том, что вы можете присваивать PChar строке String напрямую. Чтобы сделать текст именно строкой Delphi (с служебными полями длины и счётчиком ссылок), будет создан строковый буфер требуемой длины, а текст будет скопирован в него. Поэтому, даже если локальный буфер будет удалён, то текст в строковом буфере всё ещё будет с нами: Но как вам написать функцию, например в DLL, которая должна возвращать данные как PChar ? Я думаю, что вы снова можете следовать примеру GetWindowsDirectory . Вот пример простой функции из DLL, возвращающей строку версии: Как вы можете видеть, строка просто копируется в предоставленный вызывающим буфер с помощью StrLCopy . Поскольку вызывающий обязан подготовить буфер, вы избегаете любых проблем с управлением памятью. Если вы предоставляете буфер, то вы и знаете, как его удалять. FreeMem не будет работать через границу DLL (в общем случае). Но даже если бы работала (например, с использованием общего менеджера памяти – прим.пер.), то пользователь вашей DLL, работающий в C или Visual Basic, не знал бы, как освободить буфер в своём языке, т.к. управления памятью индивидуально в каждом языке. Позволяя вызывающему указывать свой буфер, вы делаете его или её независимыми от вашей реализации.

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

Delphi 2009 и выше

В Delphi 2009 строки были значительно изменены. До Delphi 2009 (т.е. с Delphi 2 по Delphi 2007) строки были, фактически, типом AnsiString , а каждый символ был однобайтовым AnsiChar . Тип PChar был псевдонимом для PAnsiChar . Но в Delphi 2009 строки стали использовать Unicode, а ещё точнее – UTF-16, что означает, что потребовался новый тип строк: UnicodeString . Этот тип строк состоит уже из двух-байтовых WideChar . Он стал умалчиваемым типом строк, что означает, что String теперь псевдоним для UnicodeString , Char для WideChar , а PChar для PWideChar .

Delphi for Win32 уже имела строковый тип WideString (также состоящий из WideChar ), но это всегда лишь псевдоним для системного типа строк BSTR , используемом в основном в COM. Этот тип управляется ОС (и поэтому является идеальным средством для обмена строками между границами модулей – прим.пер.) и не имеет счётчика ссылок и “копирования по требованию”, так что каждое присваивание означает создание новой уникальной строки с полным копированием текстового буфера. Поэтому тип WideString не отличается особой производительностью – вот почему был введён новый тип UnicodeString .

Кроме длины и счётчика ссылок, каждый строковый тип данных (т.е. AnsiString и UnicodeString ) теперь имеют дополнительные служебные поля: Word , содержащий кодировку (encoding) строки (в основном используется в однобайтовых строках типа AnsiString ), и Word , содержащий размер символа в байтах. Кодировка строки AnsiString управляет интерпретацией и конвертацией символов с кодами от 128 до 255 , а размер символа в основном используется для взаимодействия с кодом на C++.

Кроме того, также было введено несколько вспомогательных типов строк: RawByteString ( = AnsiString($FFFF) ) и UTF8String ( = AnsiString(65001) ) (а также огромного количества любых других пользовательских типов строк на базе AnsiString , например, Win1251String = AnsiString(1251) – прим.пер.). Подразумевается, что строки UTF8Strings используются для хранения данных в формате UTF-8, что означает, что каждый элемент строки является AnsiChar -ом, но каждый «символ» может быть представлен несколькими элементами AnsiChar . Заметьте, что я поставил слово «символ» в кавычки, потому что в контексте Unicode более правильно будет говорить о кодовых позициях (code point) (а также это не приведёт к путанице с символом в смысле один Char — прим.пер.).

Как вы можете видеть из статьи Википедии о UTF-16, также возможно, что некоторые кодовые позиции UTF-16 требуют нескольких WideChar -ов – так называемых «суррогатных пар» (surrogate pairs). Так что длина UnicodeString или UTF8String не обязательно напрямую соответствует числу кодовых позиций в них. Однако если в UnicodeString суррогатные пары относительно редки (суррогатные пары используются только для записи символов вне базовой плоскости: Basic Multilingual Plane (BMP) – именно там находятся все символы для всех современных языков и множество специальных символов – прим.пер.), то в то же время редкая UTF8-строка обходится без мультибайтовых символов.

Ещё одним новым типом является RawByteString . Если вы присвоите AnsiString с одним типом кодировки другой AnsiString с другой кодировкой, то будет выполнена автоматическая конвертация (потенциально: с возможной потерей данных, если символы из одной кодировки не имеют эквивалента в другой кодировке). Собственно AnsiString используют кодировку по-умолчанию, управляемую системой (“Кодировка для не-Unicode приложений” в региональных настройках системы – прим.пер.). Пользовательские типы строк на базе AnsiString всегда имеют фиксированную кодировку (например, UTF8String всегда имеет кодировку 65001 ). А RawByteString – это специальная строка без кодировки, так что вы можете быть уверены, что при присваивании ей другой AnsiString -строки (собственно AnsiString или пользовательской типа UTF8String ), никакой конвертации не будет, а все текстовые буфера будут скопированы “как есть”.

Справка Delphi 2009 так говорит о RawByteString :

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

Так что же с этим делать?

Как вы можете видеть из текста статьи, я ни разу не делал ссылок на размер Char . Так что всё, что я написал выше, полностью применимо и к Delphi 2009 и выше без изменений. Большинство кода, использующего эти техники, может быть просто перекомпилировано в Delphi 2009 и выше, и будет работать корректно, но теперь уже используя Unicode, т.е. вместо AnsiString , код будет работать с UnicodeString , WideChar и PWideChar .

Функции Win32 API часто поставляются в двух вариантах: один из которых принимает Ansi (т.е. однобайтовые) символы и (C-) строки, а второй принимает Wide (Unicode, двухбайтовые) символы и (C-) строки. Эти варианты обычно отличаются друг от друга окончаниями A или W в имени функции соответственно. Заголовочные модули Delphi для таких API функций, типа Windows.pas , обычно также определяют третий вариант, без окончаний A или W (точно так же поступает Microsoft в своих заголовочниках C), и отождествляет этот вариант с Ansi вариантом. Вот один пример из Windows.pas до Delphi 2009: Как вы можете видеть, GetShortPathName проецируется на функцию ‘GetShortPathNameA’ . Вы также можете видеть, что -A версия объявляется с PAnsiChar -ами, а -W версия принимает строки PWideChar . Нейтральная же работает с нейтральным типом PChar .

В Delphi 2009 и выше, такие нейтральные функции теперь ассоциируются с -W вариантом, так что вторая часть вышеприведённого кода теперь становится: Это означает, что в Delphi 2009 и выше, даже если вы вызываете функцию из Windows API, а также если вы вызываете функцию RTL или VCL, то в большинстве случаев вам не нужно беспокоиться о размере символов в строке. Строки теперь у нас Unicode, функции API стали тоже Unicode, так что если вы продолжите использовать нейтральные типы данных String , Char и PChar , то вам не придётся изменять свой код. А если у вас есть код, который работает с неверным размером символа (некоторые функции API, типа GetProcAddress , существуют только в ANSI варианте), то вы получите красивое предупреждение или ошибку от компилятора, так что вы тут же сможете решить, как вам реагировать (прим.пер.: вообще-то, у GetProcAddress есть перегруженный Unicode-вариант, который делает преобразование строк к ANSI-варианту).

SizeOf или Length?

Конечно же, вам нужно быть осторожным с кодом, особенно если этот код использует низко-уровневые подпрограммы типа Move или FillChar (которая теперь по-хорошему должна была бы называться FillByte , т.к. работает она с байтами, но старое название было сохранено по соображениям совместимости кода – прим.пер.), которые предполагают, что символы имеют размер в один байт (ну, на самом деле они просто меряют размеры в байтах, а не в символах – прим.пер.). Так, чтобы очистить массив из Char , не делайте так: потому что теперь буфер состоит из WideChar , что означает размер в 2 * (MAX_PATH + 1) байт. Намного проще при этом использовать SizeOf : Заметьте, что SizeOf можно применять только к статическим массивам. Для динамических массивов она всегда возвращает размер указателя (см. статью про указатели). В этом случае вам надо писать: Для ситуаций же, когда важно число символов, используйте просто Length :

Информация для дальнейшего чтения

Тут есть whitepaper от Marco Cantù, который обширно и ясно описывает различные новые строковые типы и расширения. Я рекомендую скачать её и прочитать хотя бы один раз.

Заключение

The open secrets of good design practice include the importance of knowing what to keep whole, what to combine, what to separate, and what to throw away. — Kevlin Henny

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

Как показано в тексте выше, выделение текста в функции и возвращение PChar на новый буфер не является очень хорошей идеей. Это ещё хуже в ситуациях межмодульного обмена данными, поскольку вызывающий может даже не сумеет освободить возвращаемую память – DLL и вызывающий, скорее всего, будут иметь различные менеджеры памяти – каждый со своей кучей. Также не очень хорошей идеей является использование локального буфера для возвращаемого текста.

Если вам обязательно нужно использовать PChar , потому что этого требует функция, вы должны использовать String настолько, насколько это возможно. И приводить строку к PChar только когда вы готовы передать строку параметром. Использование строк намного проще и менее подвержено ошибкам, чем использование функций строк в C-стиле.

A little inaccuracy sometimes saves a ton of explanation. — H. H. Munro (Saki)

Я надеюсь, что я немного приподнял завесу тумана над PChar . Я не рассказал всё, что известно, и даже, возможно, немного переврал правду (например, не любая Delphi-строка типа String управляется счётчиком ссылок – к примеру, строковые константы всегда имеют счётчик ссылок равный –1 (***)), но эти мелкие детали не столь важны для общей, большой картины и не оказывают влияния на использование и взаимодействие между String -ми и PChar -ми.

Дополнительный материал для чтения: тонкости работы со строками.

Примечания переводчика:
(*) Вот ещё интересный пример.
(**) Чтобы гарантировать обязательное выполнение очистки строк (уменьшения счётчика ссылок), компилятор неявно вставляет в подпрограмму скрытый try/finally. Поэтому, фактически, код любой подпрограммы со строковой переменной (а также любой другой авто-финализируемой переменной) выглядит примерно так: (***) См. также пример ситуации, где это имеет значение.

Как определить, является ли TSysCharSet (набор AnsiChar) неназначенным?

Чтобы избежать возможной ошибки в функции, мне нужно проверить, не назначена ли переменная типа TSysCharSet (или набор AnsiChar). Как мне это сделать?

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

Обратите внимание, что это не относится к этому типу. Тот же аргумент применяется к другим таким типам, например Integer , Boolean , Double и т.д.

Функции и процедуры Delphi. Справочник.

При форматировании строк с помощью функций Format, FormatBuf, StrFmt, StrLFmt, процедуры FmtStr, в качестве одного из параметров, в данных подпрограммах используется строка форматирования. Строка форматирования может содержать в себе два типа объектов — обычные символы и спецификаторы (команды форматирования). Обычные символы копируются один к одному в результирующую строку. Спецификаторы применяются для выборочного форматирования элементов из списка аргументов.

Общий вид спецификатора можно представить в следующем виде:

«%» [index «:»] [«-«] [width] [«.» prec] type

Спецификатор начинается с символа %. За ним следуют:

Необязательный параметр [index «:»], задающий индекс аргумента.
Индикатор выравнивания по левому краю [«-«] (необязательный параметр).
Необязательный параметр [width], задающий минимальную длину результирующей строки.
Необязательный параметр [«.» prec], задающий точность.
Символ преобразования типа, type.

Идентификатор type может иметь одно из значений представленных в таблице:

d Десятичный формат. Аргумент должен иметь целочисленное значение, которое будет преобразовано в строку символов десятичных цифр. Если строка форматирования содержит спецификатор точности prec, то результирующая строка должна содержать, как минимум, указанное в спецификаторе количество цифр. Если аргумент содержит меньшее количество цифр, то в результирующую строку перед значением числа будут добавлены нули.
u Десятичный беззнаковый формат. Форматируется аналогично параметру d, но знак числа не выводится.
e Научный формат. Аргумент должен представлять собой число с плавающей запятой. Значение будет преобразовано в строку формата «-d.ddd. E+ddd». Результирующая строка начинается со знака минус, если значение аргумента отрицательно. Десятичной точке всегда предшествует одна цифра. Общее количество цифр, включая стоящую перед десятичной точкой, задается спецификатором точности. Если спецификатор точности отсутствует, то используется значение по умолчанию — 15 цифр. После символа экспоненты всегда стоит знак плюс или минус и как минимум трехразрядное число.
f Фиксированный формат. Аргумент должен быть числом с фиксированной десятичной точкой. Значение аргумента будет преобразовано в строку формата «-ddd.ddd. «. Результирующая строка начинается со знака минус, если аргумент отрицателен. Количество десятичных знаков после разделителя определяется спецификатором точности prec. Если спецификатор точности отсутствует, то после десятичной точки выводятся заданные по умолчанию 2 десятичных знака.
g Общий формат. Аргумент должен быть числом с плавающей запятой. Значение аргумента преобразовывается в наиболее возможно короткую строку, используя фиксированный или научный формат. Количество значащих цифр в результирующей строке задается спецификатором точности prec. При отсутствии данного параметра выводится по умолчанию 15 знаков. Нули в конце строки не выводятся, Десятичный разделитель ставится только в случае необходимости. Фиксированный формат используется, если количество значащих цифр до десятичной точки меньше или равно значению указанному в спецификаторе точности, и если значение аргумента больше или равно 0.00001. В других случаях в результирующей строке используется научный формат.
n Числовой формат. Аргумент должен быть числом с плавающей запятой. Результирующая строка имеет вид «-d,ddd,ddd.ddd. «. Данный формат аналогичен фиксированному формату. Отличие состоит в том, что результирующая строка включает в себя разделители тысяч.
m Денежный формат. Аргумент должен быть числом с плавающей запятой. Значение аргумента преобразовывается в строку, содержащую символ, денежной единицы. Преобразование производится в соответствии со значениями глобальных переменных CurrencyString, CurrencyFormat, CurrencyDecimals, NegCurrFormat, ThousandSeparator, DecimalSeparator. Если строка формата содержит спецификатор точности prec, то значение глобальной переменной CurrencyDecimals игнорируется.
p Указатель. Аргумент должен быть указателем (тип Pointer). Значение аргумента преобразовывается в строку из 8-ми символов формата ХХХХYYYY, где ХХХХ — адрес сегмента, а YYYY — смещение в шестнадцатеричной форме.
s Строковый формат. Аргумент должен представлять собою символ, строку типа string или PChar. Значение аргумента вставляется на место спецификатора. Длина результирующей строки задается спецификатором точности prec. Если длина исходной строки превышает значение спецификатора точности, то она усекается.
x Шестнадцатеричный формат. Аргумент должен иметь целочисленное значение. Значение аргумента преобразовывается в строку шестнадцатеричных чисел. Спецификатором точности prec, задает минимальное количество символов результирующей строки. Если исходное значение содержит меньшее количество цифр, то в начало результирующей строки будут проставлены недостающие нули.

Все вышеуказанные символы могут быть записаны как в верхнем, так и в нижнем регистре.
Параметры index, width, prec могут быть заданы непосредственно числовым значением (например «%8u») или косвенно с помощью символа звездочки (например «%*.*f»). Звездочка означает, что в данной позиции будет использоваться текущее значение из массива данных (соответствующее значение должно представлять собой целочисленное значение), например вызов функции:

Результирующей строкой в обоих случаях будет ‘12345.68’

Параметр width задает минимальную длину результирующей строки. Если количество символов в получаемой строке меньше значения width, то строка дополняется необходимым количеством пробелов. По умолчанию пробелы добавляются в начало строки. Для того, чтобы пробелы добавлялись в конец строки необходимо в строку формата перед параметром width поставить символ «-«.
Параметр index определяет, какой элемент массива данных будет подвергаться форматированию. Первый элемент массива имеет индекс 0. После числового значения индекса должен стоять символ двоеточия «:». Если параметр index опускается, то форматируется элемент следующий за элементом который подвергался форматированию в прошлый раз (Первое форматирование соответственно производится для первого элемента массива данных). Например, вызов функции:

Format( ‘%3d, %d, %0:d, %2:-4d, %d’, [ 1, 2, 3, 4 ] );

будет возвращать следующую строку ‘ 1,2,1,3 ,4’

TSysCharSet — Тип Delphi

В этом уроке мы рассмотрим функции преобразования чисел в строки и строк в числа.
Давайте рассмотрим часто используемые функции StrToInt, IntToStr, FloatToStr, StrToFloat. Во многих случаях эти функции являются очень полезными в том плане, что они позволяют преобразовывать целочисленные и нецелочисленные переменные типов Integer, Byte, Double, Real и т.п. в их строковое представление в переменную типа String и обратно, если это возможно. Рассмотрим непосредственно сами функции по порядку.
[cc lang=»delphi»]var a: integer;
s: string;
begin
a := 12345;
s := IntToStr(a);
// в результате переменная s будет содержать в себе строку ‘12345’
end;[/cc]
Т.е. функция IntToStr позволяет преобразовывать целочисленную переменную типа integer или byte в ее строковое представление в переменную типа string;

Обратную возможность реализовывает функция StrToInt.
[cc lang=»delphi»]var a: integer;
s: string;
begin
s := ‘12345’; // В s должно быть введено обязательно целочисленное число без лишних символов!
// иначе программа, во время выполнения «конвертации» завершит свою работу
// с ошибкой.
a := StrToInt(s);
// в результате переменная a будет содержать в себе число 12345.
end;[/cc]

Илон Маск рекомендует:  Обзор HasLayout

Те же возможности нам помогают реализовать функции FloatToStr и StrToFloat, однако они уже позволяют работать с нецелочисленными переменными типа Double, Real и т.п. Работа с ними абсолютно аналогична работе с функциями IntToStr и StrToInt.
[note]Стоит отметить одну важную особенность при переводе строки в нецелочисленное число. В качестве плавающей запятой в «строках-числах» нужно использовать символ «точка», а не символ «запятая». При переводе нецелочисленного числа в строку эта особенность учитывается функцией FloatToStr автоматически.[/note]

TSysCharSet — Тип Delphi

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

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

Место описания данных в программе — вне логических блоков begin / end. В модуле перед ключевым словом implementation есть блок описания:

Именно здесь, начиная со следующей строки, удобно объявлять глобальные переменные и константы. Как видим, одна (Form1) уже есть!

Команда объявления переменных в языке Delphi:

var имя_переменной : тип_переменной ;

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

Если несколько описаний следуют друг за другом, то ключевое слово var повторно можно не указывать:

Постоянную величину иначе называют константой. Конечно, в программе можно использовать числа и строки непосредственно: 3.1415 или ‘Это значение числа пи’ , но иногда удобнее присвоить их идентификатору. Описание констант аналогично описанию переменных, но используется ключевое слово const, за именем идентификатора следует тип, затем знак равенства и его значение. Причём тип константы допускается не указывать:

const pi= 3.1415 ;
ZnakPi : String = ‘Это значение числа пи’ ;

К слову, константа Pi встроенная в Delphi, то есть для того чтобы использовать в Delphi число 3,1415. в расчётах, нужно просто присвоить встроенную константу Pi переменной типа Real или просто использовать непосредственно в выражениях.

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

Строкой называется последовательность символов, заключённая в одиночные кавычки:
‘это текстовая строка’ Если текст должен содержать сам символ кавычки, то его надо повторить дважды:
‘это » — символ одиночной кавычки’ Строка может быть и пустой, не содержащей символов. Тогда она состоит из двух идущих друг за другом без пробела кавычек. Естественно, строка может состоять и только из одних пробелов.
Самый популярный строковый тип — String. Строка типа String может содержать переменное количество символов объёмом до 2 Гбайт. Если нужно ограничить размер строки фиксированным значением, то после ключевого слова String в квадратных скобках указывается число, определяющее количество символов в строке: String[50]. Более полно работа со строками Delphi описывается далее.
Одиночный символ имеет тип Char и записывается в виде знака в одиночных кавычках: ‘a’. Есть символы, которые на экране отобразить невозможно, например, символ конца строки (равен #13), символ переноса строки (равен #10). Такие символы записываются в виде их числового кода (в кодировке ANSI), перед которым стоит знак #. Например, #0.
Наконец, существуют так называемые нуль-терминированные строки. Отсчёт символов в таких строках начинается с нуля, а заканчивается символом с кодом (#0). Такие строки имеют тип PChar.

Числа бывают целые и дробные.
В следующей таблице перечислены стандартные типы целых чисел и соответствующие им дипазоны допустимых значений.

Integer -2147483648 .. +2147483647
Cardinal 0 .. 4294967295
Shortint -128 .. +127
Smallint -32768 .. +32767
Int64 -2 63 .. +2 63 -1
Byte 0 .. +255
Word 0 .. +65535
Наиболее удобным для использования в программах является тип Delphi Integer. Другие целые типы используются для уменьшения места, занимаемого данными в памяти компьютера.

Дробные числа имеют дробную часть, отделяемую десятичной точкой. Допускается использование символа e (или E), за которым следует число, указывающее, что левую часть нужно умножить на 10 в соответствующей степени: 5e25 — пять умножить на десять в двадцать пятой степени.
Ниже приведены стандартные типы дробных чисел и соответствующие им диапазоны допустимых значений. Для большинства типов указан диапазон положительных значений, однако допустимым является аналогичный диапазон отрицательных значений, а также число .

Real 5*10 -324 .. 1.7*10 308
Real48 2.9*10 -39 .. 1.7*10 38
Singl 1.5*10 -45 .. 3.4*10 38
Double 5*10 -324 .. 1.7*10 308
Extended 3.6*10 -4951 .. 1.1*10 4932 -1
Comp -2 63 .. +2 63 -1
Currency 922337203685477.5807
Наиболее удобным для использования в программах является тип Delphi Real. Ему эквивилентен тип Double, но в будущем это может быть изменено. Вычисления с дробными числами выполняются приближённо, за исключением типа Currency (финансовый), который предназначен для минимизации ошибок округления в бухгалтерских расчётах.

Следующим типом данных является логический Boolean, состоящий всего из двух значений: True (Истина) и False (Ложь). При этом True > False.

Теперь, используя компоненты, их свойства и события, вводя собственные переменные, можно конструировать программы, содержащие вычисления. Осталось узнать, как вычисленное значение вывести на экран.
Про консольные программы я здесь не говорю! А в нормальных оконных Windows-приложениях это значение нужно поместить в какой-нибудь компонент, имеющий свойства Text или Caption. Это, например, такие компоненты как Label и Edit, да и сама Форма имеет свойство Caption, куда тоже можно выводить информацию. Однако, в Delphi информацию перед выводом, как правило, необходимо преобразовывать. Так как присвоение возможно только между переменными одного типа, то такая программа (не пытайтесь её исполнять):

var A, B, C: Integer ;
begin
A := 5 ;
B := 10 ;
C := A+B ;
Label1.Caption := C ;
end ;

вызовет ошибку, так как свойство Caption имеет текстовый тип String, а использованные переменные — цифровой тип Integer. Значит, нужно преобразовать значение переменной C в текстовый тип. Для этого есть встроенная функция IntToStr. Строка в нашей «программе», вызывавшая ошибку, должна выглядеть так:

Такая программа, кроме показа числа 15, ни на что не способна. Мы должны научиться вводить в программу другие числа. Используем компоненты Edit. Введённые числа будут содержаться в свойстве Text этих компонентов. Расположим на форме два компонента Edit, один компонент Label и кнопку Button, по нажатию на которую и будем проводить вычисления. В компоненты Edit1 и Edit2 будем вводить числа для суммирования. Чтобы переместиться в редактор кода, щёлкнем дважды по нашей кнопке Button1. Мы попадём прямо в сформированную для нас средой Delphi заготовку обработчика нажатия на кнопку, непосредственно между операторами begin и end. Напишем такой простой код:

procedure TForm1.Button1Click(Sender: TObject);
var A, B, C: Integer; //Не забудьте описание переменных
begin
//Начало кода:
A := Edit1.Text;
B := Edit2.Text;
C := A+B;
Label1.Caption := IntToStr(C);
//Конец кода
end ;

При попытке исполнить этот код Delphi покажет ошибки по аналогичной причине — переменные A и B имеют цифровой тип Integer, а свойство Text — текстовый тип String. Исправить ошибки поможет встроенная функция StrToInt, выполняющая обратное преобразование — текст в целое число. Операторы присвоения переменным A и B должны выглядеть так:

A := StrToInt(Edit1.Text);
B := StrToInt(Edit2.Text);

В данном случае переменные A, B, C использовались для наглядности. Можно обойтись одной строчкой:

Аналогично, имеются функции и для преобразования в строку и обратно действительных чисел c плавающей (Floating англ.) запятой, имеющих тип Real. Для преобразования в строку — FloatToStr, обратно — StrToFloat.
Часто результаты вычислений, имеющие тип Delphi Real, имеют после запятой длинный «хвост» цифр. При выводе такой переменной в текстовом виде необходимо ограничить количество цифр после запятой. Как это можно сделать, описывается также в Уроке Delphi Работа со строками Delphi.

ASD-SOFT

Программирование. Теория и практика.

TStringHelper — помощник при работе с типом String в Delphi.

Здравствуйте уважаемые коллеги!
TStringHelper, как и помощники в общем, появились в Delphi начиная с версии XE3. Ниже приведено описание и примеры использования методов и свойств помощника TStringHelper.

Empty

Возвращает пустую строку.

Create(C: Char; Count: Integer)

Создает строку из символов C количеством Count;

Create(const Value: array of Char)

Создает строку из переданного массива символов Value.

Create(const Value: array of Char; StartIndex: Integer; Length: Integer)

Создает строку из массива символов Value начиная с позиции StartIndex количеством Length символов.

Compare(const StrA: string; const StrB: string)

Сравнение двух строк StrA и StrB с учетом регистра. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; const StrB: string; IgnoreCase: Boolean)

Сравнение двух строк StrA и StrB с учетом, IgnoreCase установле в False, или без учета регистра, IgnoreCase установлен в True. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer)

Сравнить строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов с учетом регистра. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer; IgnoreCase: Boolean)

Сравнить строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов. С учетом, IgnoreCase устанавливается в False, или без учета регистра, IgnoreCase устанавливается в True. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

CompareOrdinal(const strA: string; const strB: string)

Сравнивает строку StrA со строкой StrB по кодам символов.

CompareOrdinal(const strA: string; indexA: Integer; const strB: string; indexB: Integer; length: Integer)

Сравнивает по кодам символов строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов.

CompareTo(const strB: string)

Сравнивает текущую строку со строкой StrB. Если Текущая строка StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Contains(const Value: string)

Если текущая строка содержит строку Value, то вернет True иначе False. Учитывается регистр.

Copy(const Str: string)

Возвращает строку Str.

CopyTo(SourceIndex: Integer; var destination: array of Char; DestinationIndex: Integer; Count: Integer)

Копирует текущую строку, начиная с символа SourceIndex в массив символов destination, начиная с DestinationIndex в количестве Count символов.

EndsText(const ASubText, AText: string)

Сравнивает окончание строки AText со строкой ASubText. При совпадении возвращает True.

EndsWith(const Value: string)

Сравнивает окончание текущей строки со строкой Value с учетом регистра. При совпадении возвращает True.

EndsWith(const Value: string; IgnoreCase: Boolean)

Сравнивает окончание текущей строки со строкой Value. IgnoreCase = True — без учета регистра, IgnoreCase = False — с учетом регистра. При совпадении возвращает True.

Equals(const Value: string)

Сравнивает текущую строку со строкой Value с учетом регистра. При совпадении возвращает True.

Equals(const a: string; const b: string)

Сравнивает строку a со строкой b с учетом регистра. При совпадении возвращает True.

Format(const Format: string; const args: array of const)

Подставляет значения в форматированную строку Format из массива args.

GetHashCode

В данный момент не работает. Возвращает -1.

IndexOf(value: Char)

Возвращает позицию символа value в текущей строке. Если символ не найден, вернет -1;

IndexOf(const Value: string)

Возвращает позицию совпадения строки Value с текущей строкой. Если строка не найдена, вернет -1.

IndexOf(Value: Char; StartIndex: Integer)

Возвращает позицию символа value в текущей строке, начиная с позиции StartIndex. Если символ не найден, вернет -1;

IndexOf(const Value: string; StartIndex: Integer)

Возвращает позицию совпадения строки Value с текущей строкой, начиная с позиции StartIndex. Если строка не найдена, вернет -1.

IndexOf(Value: Char; StartIndex: Integer; Count: Integer)

Возвращает позицию символа value в текущей строке, начиная с позиции StartIndex. Сравнивает Count сиволов. Если символ не найден, вернет -1.

IndexOf(const Value: string; StartIndex: Integer; Count: Integer)

Возвращает позицию совпадения строки Value с текущей строкой, начиная с позиции StartIndex, включая Count символов. Если строка не найдена, вернет -1.

IndexOfAny(const AnyOf: array of Char)

Возвращает позицию совпадения любого из массива AnyOf в текущей строке. Если ни один символ не найден, то вернет -1.

IndexOfAny(const AnyOf: array of Char; StartIndex: Integer)

Возвращает позицию совпадения любого из массива AnyOf в текущей строке, начиная с позиции StartIndex. Если ни один символ не найден, то вернет -1.

IndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer)

Возвращает позицию совпадения любого символа из массива AnyOf в текущей строке, начиная с позиции StartIndex, проверяя Count символов. Если ни один символ не найден, то вернет -1.

Insert(StartIndex: Integer; const Value: string)

Вставляет строку Value в текущую строку начиная с позиции StartIndex.

IsDelimiter(const Delimiters: string; Index: Integer)

Проверяет: присутствует ли текущая строка в строке Delimiters начиная с позиции Index.

IsEmpty

Возвращает True, если Текущая строка пустая.

IsNullOrEmpty(const Value: string)

Возвращает True, если строка Value пустая.

IsNullOrWhiteSpace(const Value: string)

Не работает. Возвращает False.

Join(const Separator: string; const values: array of const)

Не работает. Возвращает пустую строку.

Join(const Separator: string; const Values: array of string)

Объединяет значения из массива Values в строку используя разделитель Separator.

Join(const Separator: string; const Values: IEnumerable )

Не работает. Возвращает пустую строку.

Join(const Separator: string; const value: array of string; StartIndex: Integer; Count: Integer)

Объединяет значения из массива Values, начиная с позиции StartIndex количеством Count в строку используя разделитель Separator.

LastDelimiter(const Delims: string)

Возвращает последнюю совпавшую позицию строки Delims с текущей строкой. Если совпадений не найдено, то вернет -1.

LastIndexOf(Value: Char)

Возвращает последнюю позицию символа Value в текущей строке. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string)

Возвращает последнюю позицию совпадения строки Value с текущей строкой. Если строка не найдена, вернет -1.

LastIndexOf(Value: Char; StartIndex: Integer)

Возвращает последнюю позицию символа Value в текущей строке, сравнивает с начала и до позиции StartIndex. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string; StartIndex: Integer)

Возвращает последнюю позицию совпадения строки Value в текущей строке, сравнивает с начала и до позиции StartIndex. Если строка не найдена, вернет -1.

LastIndexOf(Value: Char; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию символа Value в текущей строке, сравнивает с начала и до позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию строки Value в текущей строке, сравнивает с начала и до позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char)

Возвращает последнюю позицию любого найденного символа из массива AnyOf в текущей строке. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer)

Возвращает последнюю позицию любого найденного символа из массива AnyOf в текущей строке до позиции StartIndex. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию любого найденного символа из массива AnyOf, начиная с позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

PadLeft(TotalW >Дополняет текущую строку пробелами до длинны TotalWidth слева.
PadLeft(TotalW >Дополняет текущую строку символами PaddingChar до длинны TotalWidth слева.
PadRight(TotalW >Дополняет текущую строку пробелами до длинны TotalWidth справа.
PadRight(TotalW >Дополняет текущую строку символами PaddingChar до длинны TotalWidth справа.
Remove(StartIndex: Integer)

Удаляет символы из текущей строки начиная с позиции StartIndex и до конца.

Remove(StartIndex: Integer; Count: Integer)

Удаляет Count символов из текущей строки начиная с позиции StartIndex.

Replace(OldChar: Char; NewChar: Char)

Заменяет все символы OldChar в текущей строке на симвопл NewChar.

Replace(OldChar: Char; NewChar: Char; ReplaceFlags: TReplaceFlags)

Заменяет символы OldChar в текущей строке на симвопл NewChar, используя насройки ReplaceFlags: rfReplaceAll — заменить все найденные; rfIgnoreCase — игнорировать регистр.

Replace(const OldValue: string; const NewValue: string)

Заменяет все совпадения со строкой OldValue в текущей строке на строку NewValue.

Replace(const OldValue: string; const NewValue: string; ReplaceFlags: TReplaceFlags)

Заменяет все совпадения со строкой OldValue в текущей строке на строку NewValue, используя насройки ReplaceFlags: rfReplaceAll — заменить все найденные; rfIgnoreCase — игнорировать регистр.

Split(const Separator: array of Char)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей символы из массива Separator.

Split(const Separator: array of Char; Count: Integer)

Разделяет текущую строку на массив строк TArray количеством Count, используя в качетсве разделителей символы из массива Separator.

Split(const Separator: array of Char; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей символы из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of string; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей строки из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of Char; Count: Integer; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray количеством Count, используя в качетсве разделителей символы из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of string; Count: Integer; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей строки из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

StartsWith(const Value: string)

Сравнивает начало текущей строки со строкой Value. Возвращает True при совпадении.

StartsWith(const Value: string; IgnoreCase: Boolean)

Сравнивает начало текущей строки со строкой Value. С учетом регистра при IgnoreCase = False, и без учета при IgnoreCase = True. Возвращает True при совпадении.

Substring(StartIndex: Integer)

Возвращает часть текущей строки начиная с позиции StartIndex и до конца.

Substring(StartIndex: Integer; Length: Integer)

Возвращает часть текущей строки начиная с позиции StartIndex, количеством Length символов.

ToCharArray

Преобразует текущую строку в массив символов TArray .

ToCharArray(StartIndex: Integer; Length: Integer)

Преобразует текущую строку, начиная с позиции StartIndex, количеством Length в массив символов TArray .

ToLower

Переводит все символы текущей строки в нижний регистр.

ToLowerInvariant

Переводит все символы текущей строки в нижний регистр используя UTF-16.

ToUpper

Переводит все символы текущей строки в верхний регистр.

ToUpperInvariant

Переводит все символы текущей строки в верхний регистр используя UTF-16.

Trim

Удаляет пробелы из начала и конца текущей строки.

Trim(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из начала и конца текущей строки.

TrimEnd(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из конца текущей строки.

TrimStart(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из начала текущей строки.

Chars[Index: Integer]

Свойство вернет символ с позицией Index из текущей строки.

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