Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Все, что вы не знали, но хотели бы узнать о Delphi


Выпуск №6

Раздел: Язык Программирования Delphi

Подраздел: Работа со строками

 

Уважаемый подписчик,

О чем будет следующий раздел - решать вам.

Варианты:

VCL

Системные функции и Winapi

Базы данных

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

Репортинг, работа с принтером

Работа с сетью, Интернетом, протоколами

Работа с графикой, мультимедиа

 

Ваши предложения высылайте на

formyreferal@rambler.ru

В этом выпуске:

Справочник по функциям работы со строками

Справочник по функциям работы с PChar

Функции форматирования строк

Функции преобразования UNICODE и ANSI строк

Количество вхождений подстроки в строку

Как использовать format parameter больше одного раза?

Как преобразовать String в Binary и наоборот?

Как хранятся строки?

Генерация GUID как строки

HexToStr, '4D 5A' --> 'MZ'

String --> BCD

BCD --> String

 

 

Справочник по функциям работы со строками

 


function NewStrtconst(S: String): PString;   Создает копию строки S и возвращает указатель на нее.   

procedure DisposeStr(P:
PString) ;
   Уничтожает строку, на которую указывает Р.   

procedure AssignStr(var P: PString; const S: strings)   Уничтожает строку, на которую указывает Р и затем присваивает ему адрес созданной копии строки S.   

procedure AppendStrfvar Dest: string; const S: string);   Добавляет строку S в конец строки Dest.   

function Uppercase(const S: string): string;   
Преобразует символы 'a'..'z' в строке S к верхнему регистру.
   
function LowerCase(const S: string): string;   
Преобразует символы 'A'..'Z' в строке S к нижнему регистру.
   
function CompareStr(const SI, S2: string): Integer;   Сравнивает две строки S1 и S2 с учетом регистра символов. Возвращаемое значение равно 0 в случае равенства строк или разности кодов пары первых несовпадающих символов.
   
function CompareText(const SI, S2: string): Integer;   Сравнивает две строки без учета регистра символов.   

function AnsiUpperCase(const S: string): string;   Преобразует символы в строке к верхнему регистру с учетом языкового драйвера.
   
function AnsiLowerCase(const S: string) : string;   Преобразует символы в строке к нижнему регистру с учетом языкового драйвера.
   
function AnsiCompareStr(const SI, S2: string): Integer;   Сравнивает две строки с использованием языкового драйвера и с учетом регистра символов.   

function AnsiCompareText(const SI, S2 : string) : Integer;   Сравнивает две строки с использованием языкового драйвера и без учета регистра символов.   

function IsValidldent(const Ident: string): Boolean;   Возвращает True, если строка Ident может служить идентификатором в программе на Object Pascal (т. е. содержит только буквы и цифры, причем первый символ — буква).   

function IntToStr(Value:
Longint): string;   Преобразует целое число в строку.
   
function IntToHex(Value: Longint; Digits: Integer): s t r ing ;   
Преобразует целое число в строку с его шестнадцатиричным представлением.   

function StrToInt(const S: string): Longint;   
Преобразует строку в целое число. При ошибке возникает исключительная ситуация EConvertError.   

function StrToIntDef(const S: string; Default; Longint): Longint ;   
Работает как StrToInt, но при ошибке возвращает значение Default.
   
function LoadStr(Ident: Word) : string;   
Загружает строку с индексом Ident из ресурсов приложения.   

function FmtLoadStr(Ident: Word; const Args: array of const): string;   
Загружает строку с индексом Ident из ресурсов приложения с форматированием (см. описание функции Format).   

Справочник по функциям работы с PChar

 


function StrLIComp(Strl, Str2: PChar; MaxLen: Cardinal) : Integer;   Работает как StrLComp, но без учета регистра символов.   

function StrScantStr: PChar; Chr: Char) : PChar;   Отыскивает первое вхождение символа Chr в строку Str и возвращает указатель на него или nil в случае отстутствия.   

function StrRScanfStr: PChar; Chr: Char) : PChar;   Работает как StrScan, но отыскивается последнее вхождение Chr.   

function StrPos(Strl, Str2:
PChar) : PChar;
   Отыскивает первое вхождение строки Str2 в строку Strl и возвращает указатель на нее или nil в случае отстутствия.
   
function StrUpperfStr: PChar) : PChar;   Преобразует строку к верхнему регистру.
   
function StrLower(Str:
PChar): PChar;
   Преобразует строку к нижнему регистру.   

function StrPaslStr: PChar): String;   Преобразует строку Str в строку типа string.   

function StrAlloc(Size:
Cardinal): PChar;   Размещает в куче памяти новую строку размером Size и возвращает указатель на нее.   

function StrBufSize(Str:
PChar): Cardinal;
   Возвращает размер блока памяти, выделенного для строки при помощи функции StrAlloc.   

function StrNewfStr: PChar): PChar ;   Размещает в куче памяти копню строки Str и возвращает указатель на нее.   

procedure StrDispose(Str: PChar);   Уничтожает строку, размещенную при помощи StrAlloc или StrNew.   

function StrLenfStr:
PChar):
   Возвращает число символов в строке Str (без учета завершающего нулевого).   

function StrEndfStr: PChar): PChar;   Возвращает указатель на завершающий нулевой символ строки Str.   

function StrMove(Dest, Source:
PChar; Count: Cardinal): PChar;   Копирует из строки Source в строку Dest ровно Count символов, причем строки могут перекрываться.
   
function StrCopy(Dest, Source:
PChar): PChar;   Копирует Source в Dest и возвращает указатель на Dest.
   
function StrECopy(Dest, Source:
PChar): PChar;   Копирует Source в Dest и возвращает указатель на завершающий символ Dest.
   
function StrLCopy(Dest, Source:
PChar; MaxLen: Cardinal): PChar;   Работает как StrCopy, но копирует не более MaxLen символов.
   
function StrPCopy(Dest:
PChar; const Source: String): PChar;   Копирует строку Source (типа string) в Dest и возвращает указатель на Dest.
   
function StrPLCopy(Dest:
PChar; const Source: string; MaxLen: Cardinal): PChar;   Работает как StrPCopy, но копирует не более MaxLen символов.
   
function StrCat(Dest, Source:
PChar): PChar;
   Дописывает Source к концу Dest и возвращает указатель на Dest.   

function StrLCatfDest, Source: PChar; MaxLen: Cardinal) : PChar;   Работает как StrCat, но копирует не более MaxLen-StrLen(Dest) символов.
   
function StrCoirip(Strl, Str2:
PChar): Integer;
   Сравнивает две строки (посимвольно). Возвращает значение: <0 — при Strl <Str2, 0 — при Strl =Str2, >0 — при Strl >Str2.   

function StrIComp(Strl, Str2:
PChar): Integer;   Работает как StrComp, но без учета регистра символов.
   
function StrLComp(Strl, Str2:
PChar; MaxLen: Cardinal): Integer;
   Работает как StrComp, но сравнение происходит на протяжении не более чем MaxLen символов.   

 

Функции форматирования строк

 


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

В Delphi существует группа функций форматирования строк. Их рассмотрение начнем с наиболее часто встречающегося представителя — функции Format:

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

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

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

S :Format('Product %s , version %d.%d', [ 'Borland Delphi' , 10]);

строке S будет присвоено: Product Borland Delphi , version 1.0. Рассмотрим подробнее правила, по которьм составляется форматирующая строка.

"Специальные" места в ней называются спецификаторами формата и представляют собой следующие конструкции

"%" [index":"] ["-"I [width] ["."prec] type
где обозначены:
символ -%", с которого начинаются все спецификаторы формата (обязательный);
поле индекса аргумента [ index " : " ] (необязательное);
признак выравнивания по левому краю ["-"I (необязательный);
поле ширины [width] (необязательное);
поле точности [ - . - prec ] (необязательное);
символ типа преобразования type (обязательный).

Каждый спецификатор формата соответствует как минимум одному из элементов списка аргументов и определяет, как именно рассматривать его и преобразовывать в строку.
Функция Format поддерживает следующие символы типа преобразования:
d   Десятичный   Элемент должен быть целым числом и преобразуется в строку десятичных цифр. Если при символе есть поле точности, то в выходной строке будет минимум ргес цифр; если при преобразовании числа их потребуется меньше, то строка дополняется слева нулями.   

х   Шестнадцатиричный   Как тип d, но элемент преобразуется в строку шестнадцатиричных цифр.   

е   Научный   Элемент должен быть числом с плавающей точкой. Он преобразуется к нормализованному виду -d.dddE+ddd. Перед десятичной точкой всегда находится одна цифра (при необходимости, с минусом). После символа "Е" идет показатель степени, имеющий знак и состоящий не менее чем из 3 цифр. Общее число символов в представлении числа определяется полем ргес (по умолчанию 15).   

f   Фиксированный   Элемент должен быть числом с плавающей точкой. Он преобразуется к виду -ddd.ddd. Поле ргес означает количество цифр после десятичной точки (по умолчанию 2).   

l   Обобщенный    Элемент должен быть числом с плавающей точкой. Он преобразуется к одному из двух вышеперечисленных видов — выбирается тот, который обеспечивает более короткую запись. Если требуемое число цифр слева от десятичной точки меньше значения поля ширины и само число больше 10" , применяется фиксированный тип. Удаляются все впереди идущие нули, десятичная точка (при возможности), а также символы, разделяющие строку на группы по три цифры.   

п m   Числовой Денежный   Совпадает с типом f за исключением того, что после каждой группы из трех цифр ставятся разделительные символы: d,ddd, ddd.ddd.... Элемент должен быть числом с плавающей точкой, отражающей денежную сумму. Способ ее представления зависит от значений глобальных констант, определенных в модуле SYSUTILS (см. ниже). В свою очередь, они зависят от настройки Windows на обозначения, принятые в данной стране.   

Р   Указатель   Элемент должен быть указателем. На выходе он будет представлять из себя строку шестнадцатиричных цифр вида ХХХХ: YYYY, где ХХХХ — селектор, YYYY — смещение.   

s   Строка   Элемент может иметь тип string, PChar или быть отдельным символом (Char). Эта строка (или символ) вставляются вместо спецификатора формата. Если присутствует поле ргес и длина строки больше его значения, то она усекается.   

Примечания:
1. Форматирующие символы можно задавать как в верхнем, так и в нижнем регистрах.
2. Тип преобразования m (денежный) тесно связан с правилами представления, принятыми в конкретной стране. Для этого в модуле SYSUTILS определены значения ряда типизированных констант, начальные значения которых берутся из секции [Inti] файла WIN.INI. Вы можете изменять их значения в соответствии с вашими потребностями:

CurrencyString: string[7];   Символ (или символы), добавляемые к строке с представлением денежной суммы и обозначающие национальную денежную единицу. Это может быть, например, '$', 'DM' или 'руб'.   

CurrencyFormat: Byte;   Определяет способ добавления знака денежной единицы к строке. Число 1 будет преобразовано так в зависимости от значения этого параметра: '$!' при 0; '1$' при 1; '$ Г при 2; '1 $' при 3.   

NegCurrFormat: Byte;   Определяет способ добавления знака денежной единицы и минуса к строке в том случае, если происходит преобразование отрицательного числа (к положительным числам отношения не имеет). Число -1 будет преобразовано так в зависимости от значения этого параметра: '($!)' при 0; '-$!' при 1; '$-1' при 2; '$!-' при 3; '(!$)' при 4; '-!$' при 5; 'i-$' при 6; '!$-' при 7; '-1 $' при 8; '-$ Г при 9; '$ 1-' при 10.   

CurrencyDecimals: Byte;   Число знаков после запятой в представлении денежных сумм. Например, число 10.15 при разных значениях этого параметра отобразится так: '$10' при 0, '$10.15' при 2, '$10.1500' при 4.   

ThousandSeparator: Char;   Символ, разделяющий строку на группы по три цифры справа налево (разделитель тысяч). Применяется, в частности, в типе преобразования п.   

DecimalSeparator: Char;   Символ, отделяющий дробную часть числа от целой.   

Мы закончили рассмотрение символа типа преобразования. Рассмотрим остальные составные части спецификатора формата.

Поле ширины устанавливает минимально допустимое количество символов в преобразованной строке. Это означает, что если она короче, чем задано в этом поле, то происходит добавление пробелов до требуемого количества. По умолчанию пробелы добавляются спереди (выравнивание по правому краю), но признак выравнивания по левому краю ("-"; он должен стоять перед полем ширины) позволяет выравнивать строку по-иному.

Поле индекса позволяет динамически изменить последовательность извлечения аргументов из массива. Обычно аргументы извлекаются последовательно, по мере их востребования спецификаторами формата. Поле индекса означает, что следующим нужно извлечь аргумент с данным индексом. Пользуясь индексом, одни и те же аргументы могут быть использованы многократно. Например
, вызов Format ( ' %s %s %0 : s %s ', [ 'Yes', 'No' ] ) Даст на выходе строку 'Yes No Yes No'.

Поле точности играет разную роль в зависимости от того, с каким типом преобразования применяется. Его особенности приведены вместе с описанием типа (с теми из них, где оно имеет смысл).
Поля индекса, ширины и точности могут быть заданы напрямую или косвенно. Первый способ подразумевает явное указание значения поля (например, ' %10 . 5f '). Для косвенного задания значений нужно в соответствующих местах цифры заменить звездочками (например, '%*.*f'). В этом случае вместо звездочек будут подставлены следующие значения из списка аргументов (они обязательно должны быть целыми числами). Например, выражение

Format('Value is %*.*',[10,52.718]);
эквивалентно:
Format('Value is %10.5',[2.718]);

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

procedure FmtStr(var Result: string; const Format: string; const Args: array of const);   To же, что и Format, но оформлено в виде процедуры. Результат преобразования возвращается в параметре Result.   

function StrFmt(Buffer, Format:
PChar; const Args: array of const): PChar;   Форматирующая строка должна находиться в параметре Format, а результирующая помещается в буфер Buffer (он должен иметь нужную длину). Функция возвращает указатель на Buffer.   

function StrLFmt(Buffer:
PChar; MaxLen: Cardinal; Format: PChar; const Args: array of const) : PChar;   Работает как StrFmt, но длина результирующей строки не будет превышать MaxLen символов.
   
function FormatBuf(var Buffer; BufLen:
Cardinal; const Format; FmtLen: Cardinal; const Args: array of const) : Cardinal;
   Форматирующая строка находится в буфере Format длиной FmtLen, a результирующая — в буфере Buffer длиной BufLen. Функция возвращает число реально помещенных в Buffer символов, причем оно всегда меньше или равно BufLen.   

 

Функции преобразования UNICODE и ANSI строк

 


StringToWideChar    Преобразовывает строку формата ANSI в Unicode-строку.

WideCharLenToString Преобразовывает указанное количество символов Unicode-строки в ANSI строку.

WideCharLenToStrVar Преобразовывает заданное количество символов Unicode-строки в ANSI формат и копирует результат в указанную переменную.

WideCharToString Преобразовывает длинную строку Unicode в ANSI строку.

WideCharLenToStrVar Преобразовывает строку формата Unicode в ANSI-формат и копирует результирующую строку в указанную переменную.

Количество вхождений подстроки в строку

 


function CountPos(const subtext: string; Text: string): Integer;
begin
  
if (Length(subtext) = 0or (Length(Text) = 0or (Pos(subtext, Text) = 0then
    Result := 
0
  
else
    Result := (Length(Text) - Length(StringReplace(Text, subtext, 
'', [rfReplaceAll]))) div
      Length(subtext);
end;

Как использовать format parameter больше одного раза?

 


Sometimes you probably have written something like this:

s := Format('Hello %s, your name is %s %s', [FirstNameFirstNameLastName]);

(an admittedly stupid example ;-) )

And if you do, you probably found it annoying that you need to specify the FirstName parameter
twice, in particular if there are lots of similar lines.

But this isn't necessary because you can specify the parameter position to use for the placeholder
in the format string like this:

s := Format('Hello %0:s, your name is %0:s %1:s', [FirstNameLastName]);

Just one more example from a code generator I am currently writing:

TableName := 'Customer';
...
s := Format(
' f%0:sTableAuto := T%0:sTableAuto.Create(f%0:Table);', [TableName]);

which results in

s := fCustomerTableAuto := TCustomerTableAuto.Create(fCustmerTable);';

Как преобразовать String в Binary и наоборот?

 



Автор: Rem
function BinStrToByte(a_sBinStrstring): byte;
var
 i: integer;
begin
 Result := 
0;
 
for i := 1 to length(a_sBinStrdo
   Result := (Result 
shl 1or byte(a_sBinStr[i] = '1');
end;

function ByteToBinStr(a_bByte: byte): string;
var
 i: integer;
begin
 SetLength(Result, 
8);
 
for i := 8 downto 1 do
 
begin
   Result[i] := chr(
$30 + (a_bByte and 1));
   a_bByte := a_bByte 
shr 1;
 
end;
end;

// Примечаниевторая функция использует тот факт,
// что в таблице ANSI коды '0' = $30 и '1' = $31

Как хранятся строки?

 


Тип String:
по смещению -4 храниться длина строки
по смещению -8 храниться счётчик ссылок на строку (когда он обнуляется строка уничтожается)
Сама строка располагается в памяти как есть - каждая буква занимает 1 байт.
При копировании строки:
s1:=s2 - реального копирования не происходит, увеличивается только счётчик ссылок, но если после этого изменить одну из строк:
s1:=s1+'a';
то произойдёт физическое копирование содержимого строк, и теперь s1 и s2 будут показывать на разные адреса памяти.
PChar - длина строки определяется от начала до #0 байта, по сути это чистой воды pointer, так что все действия по отслеживанию распределения памяти лежат на программисте - сами заботьтесь о том чтобы хватило места для распределения памяти и освобождении после использования. Тоже одна буква = 1 байт
Д
ля хранения unicode (т.е. 2х байтовых символов) используйте соответствующие символы с приставкой Wide...

Генерация GUID как строки

 


Как в Run-time сгененрировать строку типа

'{821AB2C7-559D-48E0-A3EE-6DD50E83234C}'

Типа как в среде при нажатии Ctrl-Shift-G. Функция CoCreateGuid выводит значение типа TGUID, я нигде не нашёл функции конвертации TGUID -> String. Может кто знает такую функцию?


Есть такая функция. Как ни странно называется она GUIDToString, и живет в SysUtils.



Можно GUIDToString написать и вручную, будет выглядеть примерно так:

procedure TForm1.Button1Click(Sender:
 TObject);
var
  G: TGUID;
  S: 
string;
  i: Integer;
begin
  CoCreateGuid(G);
  S := 
'{' + IntToHex(G.D1, 8) + '-' + IntToHex(G.D2, 4) + '-' + IntToHex(G.D3, 4) + '-';
  
for i := 0 to 7 do
    
begin
      S := S + IntToHex(G.D4[i], 
2);
      
if i = 1 then S := S + '-'
    
end;
  S := S + 
'}';
  ShowMessage(GUIDToString(G) + 
#13 + S)
end;

 

 

HexToStr, '4D 5A' --> 'MZ'

 


procedure TForm1.Button1Click(Sender: TObject);
const Source: string = '4D 5A';
var S: string;
  t: Integer;
begin
  
with TStringList.Create do
  
try
    Text := StringReplace(Source, 
#32#13#10, [rfReplaceAll]);
    S := 
'';
    
for t := 0 to Count - 1 do
      S := S + Chr(StrToInt(
'$' + Strings[t]));
    ShowMessage(S);
  
finally
    Free;
  
end;
end;

String --> BCD

 


function NumStringToBCD(const inStrstring): string;
  
function Pack(ch1, ch2: Char): Char;
  
begin
    Assert((ch1 >= 
'0'and (ch1 <= '9'));
    Assert((ch2 >= 
'0'and (ch2 <= '9'));
      
{Ord('0') is $30, so we can just use the low nybble of the character
       as value.}

    Result := Chr((Ord(ch1) 
and $For ((Ord(ch2) and $Fshl 4))
  
end;
var
  i: Integer;
begin
  
if Odd(Length(inStr)) then
    Result := NumStringToBCD(
'0' + instr)
  
else begin
    SetLength(Result, Length(inStr
div 2);
    
for i := 1 to Length(Result) do
      Result[i] := Pack(inStr[
2 * i - 1], inStr[2 * i]);
  
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  S1, S2: 
string;
begin
  S1 := 
'15151515151515151515';
  S2 := NumStringToBCD(S1);
  memo1.lines.add(
'S1: ' + S1);
  memo1.lines.add(
'Length(S2): ' + IntToStr(Length(S2)));
  memo1.lines.add(
'S2 unpacked again: ' + BCDToNumString(S2));
end;

BCD --> String

 


function BCDToNumString(const inStrstring): string;
  
procedure UnPack(ch: Char; var ch1, ch2: Char);
  
begin
    ch1 := Chr((Ord(ch
and $F) + $30);
    ch2 := Chr(((Ord(ch
shr 4and $F) + $30);
    Assert((ch1 >= 
'0'and (ch1 <= '9'));
    Assert((ch2 >= 
'0'and (ch2 <= '9'));
  
end;
var
  i: Integer;
begin
  SetLength(Result, Length(inStr) * 
2);
  
for i := 1 to Length(inStrdo
    UnPack(inStr[i], Result[
2 * i - 1], Result[2 * i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  S1, S2: 
string;
begin
  S1 := 
'15151515151515151515';
  S2 := NumStringToBCD(S1);
  memo1.lines.add(
'S1: ' + S1);
  memo1.lines.add(
'Length(S2): ' + IntToStr(Length(S2)));
  memo1.lines.add(
'S2 unpacked again: ' + BCDToNumString(S2));
end;

Сайт рассылки Здесь

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

Hit&Host

 

Raskrutim.ru

 

WmSearch

 


В избранное