StrScan — Функция Delphi

Клуб программистов

Delphi programming

Подписаться на рассылку:

StrScan

Ищет заданные символы в строке

Описание:

StrScan используется в тех случаях, когда вам нужно найти единичный символ в списке известных символов (Characters).

Если SearchChar (искомый символ) присутствует в Characters, то в качестве результата функции возвращается указатель на Characters.

Если символ отсутствует, то возвращается nil.

Пример кода:

const
Numbers = ‘0123456789’;
begin
if StrScan(Numbers, ‘2’) <> nil
then ShowMessage(‘2 is a numeric digit’)
else ShowMessage(‘2 is not a numeric digit’);

if StrScan(Numbers, ‘A’) <> nil
then ShowMessage(‘A is a numeric digit’)
else ShowMessage(‘A is not a numeric digit’);
end;

StrScan — Функция Delphi

Cледующие функции обеспечивают работу со строками с завершающим нулем:

Функции работы со строками с завершающим нулем.
Функция Описание
AnsiStrComp Сравнивает две строки с завершающим нулем.
AnsiStrIComp Сравнивает две строки с завершающим нулем без учета регистра.
AnsiStrLComp Сравнивает первые MaxLen байт двух строк с завершающим нулем, с учетом регистра.
AnsiStrLIComp Сравнивает первые MaxLen байт двух строк с завершающим нулем, без учета регистра.
AnsiStrLower Переводит все символы строки с завершающим нулем в нижний регистр.
AnsiStrPos Возвращает указатель на первое вхождение заданной подстроки в строку.
AnsiStrRScan Возвращает указатель на последнее вхождение заданного символа в строку.
AnsiStrScan Возвращает указатель на первое вхождение заданного символа в строку.
AnsiStrUpper Переводит все символы строки с завершающим нулем в верхний регистр.
ExtractStringth Заполняет список (массив) строк подстроками, из строки с завершающим нулем, которые отделены друг от друга разделителями.
LineStart Ищет конец последней полной строки (знак перевода каретки) в буффере.
SearchBuf Находит подстроку внутри текстового буфера.
StrAlloc Выделяет память под символьный буфер, заданного размера, в «куче» .
StrBufSize Возвращает размер символьного буфера, выделенного при помощи StrAlloc или StrNew.
StrCat Соединяет две строки в одну.
StrComp Сравнивает две строки между собой.
StrCopy Копирует строку.
StrDispose Освобождает символьный буфер, выделенный при помощи StrAlloc или StrNew.
StrECopy Копирует строку и возвращает указатель на коец строки.
StrEnd Возвращает указатель на конец строки.
StrFmt Форматирует одно или более значений в строке.
StrIComp Сравнивает две строки без учета регистра.
StrLCat Соединяет две строки в одну результирующую строку, с заданной максимальной длинной.
StrLComp Сравнивает две строки на заданной максимальной длине.
StrLCopy Копирует строку до заданной максимальной длины.
StrLen Возвращает длину строки.
StrLFmt Форматирует одно или более значений в строке на заданной максимальной длине.
StrLIComp Сравнивает две строки на заданной максимальной длине без учета регистра.
StrLower Переводит строку в нижний регистр.
StrMove Переносит блок символов из одной строки в другую.
StrNew Помещает строку в «кучу».
StrPCopy Копирует строку AnsiString (длинную строку Paskal) в строку с завершающим нулем.
StrPLCopy Копирует строку AnsiString (длинную строку Paskal) в строку с завершающим нулем с заданной максимальной длиной.
StrPos Возвращает указатель на первое вхождение заданной подстроки в строку.
StrRScan Возвращает указатель на последнее вхождение заданного символа в строку.
StrScan Возвращает указатель на первое вхождение заданного символа в строку.
StrUpper Переводит строку в верхний регистр.

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

При работе со строками с завершающим нулем целесообразно использовать расширенный синтаксис языка Delphi, который задается компилятору директивой (хотя ее можно не указывать в начале программы, т.к. она устанавливается по умолчанию). Расширенный синтаксис позволяет использовать особые правила для стандартного типа PChar и массивов с нулевым индексом. В частности стандартные процедуры Read, ReadLn, Str и Val могут быть использованы с такими массивами, а процедуры Write, WriteLn, Val, AssignFile и Rename могут применяться как с массивами, так и с символьными указателями.

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

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

Стандартные функции работы со стандартными строками имеют аналоги для работы с мультибайтными строками (AnsiString), которые к тому же обеспечивают прядок сортировки символов в соответствии с установками национального алфавита. В типе AnsiString символы кодируются в коде ANSI. Имена мультибайтных функций начинаются с Ansi-. Например, мультибайтная версия функции StrPos будет AnsiStrPos. Поддержка мультибайтных символов зависит от оперативной системы и базируется на ее текущей локализации.

Илон Маск рекомендует:  Операторы vba

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

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

StrScan — Функция Delphi

С StrScan определенно что-то не так. Писал парсер и удивлялся почему он так медленно работает, хотя везде использую PChar и вообще все должно было работать на ура. Тогда уже стал замерять определенные участки кода вот такими вещами:
Time := GetTickCount;
код
Inc(TimeSum, GetTickCount-Time);
и выяснил что бутылочным горлышком является как раз функция StrScan(). Причем замедление от нее было такое что парсинг с ней выполнялся у меня

10 секунд, а после замены ее на паскальную версию из SysUtils время выполнения стало исчисляться десятками миллисекунд!

Хм, и еще заметил вещь непонятную.
Есть две процедуры: одна <1>— парсер работает много с PChar и глубокая рекурсия, вторая <2>— работа с MemStream, много записи в поток.
И вот замечена такая вещь: если отключена замена системных dcu, то <1>выполняется

11 секунд! Если же включить замену, то <1>выполняется

460 миллисекунд. Вот я не пойму откуда такая разница?! И ладно бы с заменой было бы медленней, ну там менеджер памяти может другой стоит, дак нет ведь <1>медленней, а <2>намного быстрей! Проект каждый раз я пересобираю (build), проверил уже несколько раз — история повторяется. Из-за чего такое может происходить?! Как такое объяснить?!
P.S. У меня Д7. Кстати, похоже что в замененных модулях для Д7 нету UseDelphiMemoryManager. А какой менеджер там стоит по умолчанию: дельфийский или свой какой-то и как его тогда поменять потому что на UseDelphiMemoryManager компилятор ругается.

Ай, пардон, насчет UseDelphiMemoryManager соврал, есть такой. Попробовал его и результат получился как уже выше описано с отключенными dcu! Как это можно объяснить? Все всегда кричат что наоборот в замененных библиотеках тормозной менеджер памяти, ан нет, получается что не всегда

в замененных библиотеках по умолчанию работа начинается с упрощенного менеджера памяти, который весь состоит из 3 строк кода. Ясно, что он будет тормозить, т.к. не содержит никакой оптимизации. Для простых случаев этого достаточно. Вызов UseDelphiMemoryManager устанавливает тот менеджер памяти, который изначально сделан фирмой Borland — Inprise и оптимизирован для многократного выделения и освобождения мелких кусочков памяти, что и происходит при интенсивной работе с AnsiString. Но если НЕ ИСПОЛЬЗОВАТЬ AnsiString и переделать алгоритм так, чтобы работа шла исключительно с PChar, без постоянного выделения и освобождения памяти, то можно получить ускорение по сравнению с прежним алгоритмом в сотни раз, даже если использовался стандартный менеджер памяти.

По оптимизации работы с потоками в памяти могу добавить: они тоже вообще не оптимизируются автоматически. Потому что для минимальных целей и так работает. Если надо оптимизировать, это очень просто: заранее укажите требуемый Size для потока. И тогда при записи по одному байту не будет происходить перевыделение памяти для всего потока. Другой вариант: перед записью проверять, что Position+AddedBytes

Ну а что насчет StrScan? Тут вне зависимости от менеджера памяти asm-версия из KOL работает намноого медленней чем pascal версия выдернутая из SysUtils

а в исходники заглянуть — лень?

function StrScan(Str: PChar; Chr: Char): PChar; assembler;
asm
<$IFDEF F_P>
MOV EAX, [Str]
MOVZX EDX, [Chr]
<$ENDIF>
PUSH EDI
PUSH EAX
MOV EDI,Str
OR ECX, -1
XOR AL,AL
REPNE SCASB
NOT ECX
POP EDI
XCHG EAX, EDX
REPNE SCASB

XCHG EAX, EDI
POP EDI

JE @@1
XOR EAX, EAX
RET

function StrScan(const Str: PChar; Chr: Char): PChar; assembler;
asm
PUSH EDI
PUSH EAX
MOV EDI,Str
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
POP EDI
MOV AL,Chr
REPNE SCASB
MOV EAX,0
JNE @@1
MOV EAX,EDI
DEC EAX
@@1: POP EDI
end;

найдите 10 отличий

А я что не смотрел в исходники? Естественно смотрел. Сейчас попробовал обе эти функции и результат тот же самый. При использовании функций что дали вы, время выполнения

12-13 секунд вне зависимости от исполльзования замены системных библиотек или нет. При использовании вот такой функции:
function StrScan(const Str: PChar; Chr: Char): PChar;
begin
Result := Str;
while Result^ <> Chr do
begin
if Result^ = #0 then
begin
Result := nil;
Exit;
end;
Inc(Result);
end;
end;
Без замены системных библиотек я получил 20мс.
И с заменой 231мс!
Почему получается что асм-версия работает настооолько медленней?

Потому, что в ASM функции сначала ищется конец строки, а потом ищется нужный символ. Т. е. сканирование производится дважды, но быстро (REPNE SCASB). На коротких строках это дает выигрыш. У тебя, наверное, строки очень длинные, поэтому предпочтительнее твой вариант. А еще лучше его аналог на асме.

Функция SysUtils.StrScan () для строкового типа? где?

В то время как SysUtils.StrScan () принимает PWideChar const в качестве параметра, есть ли встроенная функция типа StrScan () для строкового / уникального типа?

1 ответ

Обычный старый Pos будет работать достаточно хорошо в большинстве случаев. Второй параметр будет просто односимвольной string вместо Char .

Если StrScan строка не будет иметь встроенных нулевых символов, вы также можете использовать StrScan напрямую; просто приведите строковый параметр к PChar . StrScan прекратит поиск, когда достигнет нулевого символа.

sscanf в Delphi

Delphi , Синтаксис , Текст и Строки

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

Статья sscanf в Delphi раздела Синтаксис Текст и Строки может быть полезна для разработчиков на Delphi и FreePascal.

Комментарии и вопросы

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

striscan

Scan a string for a character, case-insensitive

Declaration

Source position: strings.pp line 71

Description

striscan does the same as strscan but compares the characters case-insensitively. It returns a pointer to the first occurrence of the character c in the null-terminated string p , or Nil if c is not present in the string.

See also

Find first occurrence of a character in a null-terminated string.

Scan a string reversely for a character, case-insensitive

StrScan Routine

Description

(Please provide a description in your own words. It is illegal to use the wording from the Delphi Help.)

Technical Comments

(Known issues / Documentation clarifications / Things to be aware of)

Examples

(Please provide links to articles/source code that show how to use this item.)

See Also

(Please provide links to items specifically related to this item.)

User Comments/Tips

(Please leave your name with your comment.)

Справочник по компонентам Delphi. Часть 1

Written on 15 Сентября 2006 . Posted in Delphi

ОГЛАВЛЕНИЕ

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

В Delphi вынужденно уживаются два стандарта работы со строковыми дан­ными. Первый из них, когда длина строки записывается в ее первом байте, традиционен для Паскаля. Ему соответствует тип данных string. Другой подразумевает, что строка заканчивается нулевым символом. Такие строки имеют тип PChar и применяются в основном при обращении к функциям API Windows.

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

Первая таблица содержит функции для работы с типом string. Все перечисленные в ней функции находятся в модуле SYSUTILS.

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 (также находятся в модуле SYSUTILS):

Функция SysUtils.StrScan () для строкового типа? где?

В то время как SysUtils.StrScan () принимает PWideChar сопзЬ в качестве параметра, есть StrScan (), как встроенная функция для строки / типа UnicodeString?

Обычный старый Pos будет работать достаточно хорошо для большинства случаев. Второй параметр будет просто один-символ string вместо Char .

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

Справочник по компонентам Delphi. Часть 1
Страница 7. Функции работы со строками

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

В Delphi вынужденно уживаются два стандарта работы со строковыми дан­ными. Первый из них, когда длина строки записывается в ее первом байте, традиционен для Паскаля. Ему соответствует тип данных string. Другой подразумевает, что строка заканчивается нулевым символом. Такие строки имеют тип PChar и применяются в основном при обращении к функциям API Windows.

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

Первая таблица содержит функции для работы с типом string. Все перечисленные в ней функции находятся в модуле SYSUTILS.

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 (также находятся в модуле SYSUTILS):

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.

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

function StrEndfStr: PChar): PChar;

Возвращает указатель на завершающий нулевой символ строки Str.

function StrMove(Dest, Source: PChar; Count: Cardinal): PChar;

Копирует из строки Source в строку Dest ровно Count символов, причем строки могут пере­крываться.

function StrCopy(Dest, Source: PChar): PChar;

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;

function StrLCatfDest, Source: PChar; MaxLen: Cardinal) : PChar;

Работает как StrCat, но копирует не более MaxLen-StrLen(Dest) символов.

function StrCoirip(Strl, Str2: PChar): Integer;

Сравнивает две строки (посимвольно). Возвра­щает значение: 0 — при Strl >Str2.

function StrIComp(Strl, Str2: PChar): Integer;

Работает как StrComp, но без учета регистра символов.

function StrLComp(Strl, Str2: PChar; MaxLen: Cardinal): Integer;

Работает как StrComp, но сравнение происходит на протяжении не более чем MaxLen символов.

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