EPasStr, Extra Strings (pascal and ANSI string) routines

I finally decided to create an helpfile for EPasStr. Stupid because it's my most used unit :-)



Additional remarks, bugs and principles.

EPasstr contains all stringhandling for Pascal and Ansistrings. It doesn't contain PChar handling, those are in EStrings, to allow easier usage and compiling in BP (remember that BP doesn't support overloading). The ansistring handling IS included in EPasStr because the AnsiString isn't available under BP, only under FPC

Since for the user the differences between Pascal and Ansistrings are quite small, I explain a certain procedure for both types in one paragraph.



rocedures



Additional remarks, bugs and principles.

Pascal strings

These procedures have been in use for a while now. The pascal routines should be stable, and the assembler ones also (I use the assembler routines by default, and haven't found a bug in more than two months). The more complex procedures (specially the *tab* procedures) can have some small errors, since they aren't used (and put to the test) as much.

Ansi (Delphi) strings

Alpha. Not tested much (I hardly use them in my own programs), but most routines are derived from tested Pascal string procedures with some adjustments specific to AnsiStrings, so I don't expect real surprises.

For ansistrings only the charpos and procedures it's variants have been ported to assembler. In time, probably all procedures which don't expand the ansistring will be ported to assembler. Since AnsiStrings are dynamic, the benefits are much less (a getmem might require more time than the entire procedure). However the above routines are ported to ansistrings quite fast. (the 5 charpos procedures took 15 minutes all together), and for core-routines (EPasStr is my most used unit) I think it is worth the effort



Types

Right now, EPasStr has one type, CHARSET, which I think should be included it the RTL(since it's the most used set-type).

TYPE CHARSET=SET OF CHAR; { I'm quite fond of the SET OF CHAR
                             construction in string routines
                             (relatively) slow, but very powerfull,
                             and safe, you filter out all unwanted characters}


LTrim

Declaration

PROCEDURE LTrim (VAR P : String;Ch:CHAR);
PROCEDURE LTrim (VAR P : AnsiString;Ch:Char);

Description

Strips all characters Ch from the left (beginning) of the string P.

See also

Uses None

Example


VAR S : String;

BEGIN
 P:='       text';
 LTrim(P,' ');
 Writeln(P);            {writes 'text'}
END;



RTrim

Declaration

PROCEDURE RTrim(VAR P:String;Ch:Char);
PROCEDURE RTrim(VAR P : AnsiString;Ch:Char);

Description

Strip all characters Ch from the right (end) of the string P.

See also

Uses None

Example


VAR P : String;

BEGIN
 P:='text     ';
 RTrim(P,' ');
 Writeln(P);            {writes 'text'}
END;



KillChar

Declaration

PROCEDURE KillChar(VAR S : STRING;CONST CSet:CHARSET);
PROCEDURE KillChar(VAR S : AnsiString; CONST CSet:CHARSET);

Description

LTrim but then for an entire character set. Strips all characters in set Ch from beginning (left) of string P

See also

Uses None

Example


VAR P : String;

BEGIN
 P:='A B A B A Btext';
 KillChar(P,['A','B',' ']);
 Writeln(P);                   {writes 'text'}
END;



KillBChar

Declaration

PROCEDURE KillBChar(VAR S : AnsiString;CONST CSet:CHARSET);
PROCEDURE KillBChar(VAR S : String;CONST CSet:CHARSET);

Description

RTrim but then for an entire character set. Strips all characters in set Ch from right (ending) of String P

See also

Uses None

Example


VAR P : String;

BEGIN
 P:='textA B A B A B';
 KillBChar(P,['A','B',' ']);
 Writeln(P);            {writes 'text'}
END;


AppendBackslash

Declaration

PROCEDURE AppendBackSlash(VAR S : String);
PROCEDURE AppendBackSlash(VAR S : AnsiString);

Description

Appends a backslash ('\') to the end of a string if it's not already there.

Under Linux it appends a '/'. Used as a primitive for programs which create a lot of paths.

Using this procedure makes programs more safe. The Dos rtl procedures (the LFN ones anyway) don't work right on paths with two backslashes in it, probably because of the UNC (\\server\sharename) notation of networkdrives.
Using (P)AppendBackslash avoids such problems because it doesn't append a backslash if it's already there, like S:='S'+'\'+name; would.

Uses None

Example


VAR P : String;

BEGIN
 P:='text\';
 AppendBackslash(P);
 Writeln(P);            {writes 'text\'}
 P:='text';
 AppendBackslash(P);
 Writeln(P);            {writes 'text\'}
END;


ReplaceChar

Declaration

PROCEDURE ReplaceChar(VAR S :String;ReplaceMe,ReplaceWith:CHAR);
PROCEDURE ReplaceChar(VAR S :AnsiString;ReplaceMe,ReplaceWith:CHAR);

Description

Replace in string the character "ReplaceMe" with "RepWith"

Uses None

Example


VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 ReplaceChar(S,'A','B');
 Writeln(P);                   {writes 'text\ B B B B B '}
END;


StripChar

Declaration

PROCEDURE StripChar(VAR S : String;C:CHAR);
PROCEDURE StripChar(VAR S : AnsiString;C:CHAR);

Description

Remove all characters C from string S.

Uses None

See AlsoKillChrTot

Example


VAR P : string;

BEGIN
 GetMem(P,100);
 P:='text\ A A A A A ';
 StripChar(S,'A');
 Writeln(P);            {writes 'text\      '}
END;


KillChrTot

Declaration

PROCEDURE KillChrTot(VAR S : String;CONST CSet:CHARSET);
PROCEDURE KillChrTot(VAR S : AnsiString;CONST CSet:CHARSET);

Description

Remove all characters in set C from string S.

Uses None

See AlsoStripChar

Example



VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 KillChrTot(S,['A',' ']);
 Writeln(P);            {writes 'text\'}
END;


CharPos

Declaration

FUNCTION CharPos(CONST S : String;C:CHAR):LONGINT;
FUNCTION CharPos(CONST S : AnsiString;C:CHAR):LONGINT;

Description

Pos for one char only. Faster than an ordinary Pos, 0 when not found.

CharPos starts searching at the beginning of the array of char/string

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 Writeln(CharPos(P,'A'));  {writes 7 }
END;


RCharPos

Declaration

FUNCTION RCharPos(CONST S : String;C:CHAR):LONGINT;
FUNCTION RCharPos(CONST S : AnsiString;C:CHAR):LONGINT;

Description

Pos for one char only. Faster than an ordinary Pos, 0 when not found, this version starts searching at the back of the string. It returns a standard index in the string. (1..Length(S), 0 if not found).

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 Writeln(RCharPos(P,'A'));  {writes 15 }
END;


NextCharPos

Declaration

FUNCTION NextCharPos(CONST S : String;C:CHAR;Count:LONGINT):LONGINT;
FUNCTION NextCharPos(CONST S : AnsiString;C:CHAR;Count:LONGINT):LONGINT;

Description

Pos for one char only. Faster than an ordinary Pos, 0 when not found, this version starts searching at character number count, and searches towards the end of the string

It returns a standard index in the string (1..Length(S), or 0 when not found).

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 Writeln(NextCharPos(P,'A',8));  {writes 9}
END;


NextCharPosSet

Declaration

FUNCTION NextCharPosSet(CONST S : String;C:CHARSET;Count:LONGINT):LONGINT;
FUNCTION NextCharPosSet(CONST S : AnsiString;C:CHARSET;Count:LONGINT):LONGINT;

Description

Pos for all characters in a set. Relatively slow (compared to an ordinary CharPos), but very powerful when parsing

Returns 0 when not found, this version starts searching at character number count, and searches towards the end of the string for characters in the set C

It returns a standard index in the string (1..Length(S), or 0 when not found).

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A B A A A ';
 Writeln(NextCharPosSet(P,['A','B'],8));  {writes 9}
END;


NextRCharPos

Declaration

FUNCTION NextRCharPos(CONST S : String;C:CHAR;Count:LONGINT):LONGINT;
FUNCTION NextRCharPos(CONST S : AnsiString;C:CHAR;Count:LONGINT):LONGINT;

Description

Pos for one char only. Faster than an ordinary Pos, 0 when not found, this version starts searching at character number count, and searches back to the beginning ofthe string

It returns a standard index in the string (1..Length(S), or 0 when not found).

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 Writeln(NextRCharPos(P,'A',14));  {writes 13 (the last but one A)}
END;


CharPosSet

Declaration

FUNCTION CharPosSet(CONST S : String;CONST CSet:CHARSET):LONGINT;
FUNCTION CharPosSet(CONST S : AnsiString;CONST CSet:CHARSET):LONGINT;

Description

Returns the first occurance in string S of a character in charset CSet, returns 0 when not found, the position of the character (1..Lengt(S)) otherwise.

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='text\ A A A A A ';
 Writeln(CharPosSet(P,['A','\']));  {writes 5 }
END;


StripDoubleChar

Declaration

PROCEDURE StripDoubleChar(VAR S : String;C:CHAR);
PROCEDURE StripDoubleChar(VAR S : AnsiString;C:CHAR);

Description

Cleans a string of double(of more) sequences of char C.

Used to make mail from Fido and Newsgroup newbies readable (with a StripDoubleChar for '.', '!' and space) :-)

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:=' 1 2  3   4    5';
 StripDoubleChar(P,' ');
 Writeln(P);               { Writes ' 1 2 3 4 5'}
END;


RGrow

Declaration

PROCEDURE RGrow(VAR S : String;C:CHAR;Count:LONGINT);
PROCEDURE RGrow(VAR S : AnsiString;C:CHAR;Count:LONGINT);

Description

Make string P at least Count characters big. Pad right (at end of string) with character C.

Uses None

See Also

Example

VAR P : String;

BEGIN
 P:='1');
 RGrow(P,' ',10);
 Writeln(P);            { Writes '1        '}
END;


LGrow

Declaration

PROCEDURE LGrow(VAR S : String;Ch:CHAR;Count:LONGINT);
PROCEDURE LGrow(VAR S : AnsiString;Ch:CHAR;Count:LONGINT);

Description

Make string P at least Count characters big. Pad left (beginning of string) with character C.

Uses None

See Also

Example

Uses EPasStr;

VAR P : String;

BEGIN
 P:='1';
 LGrow(P,' ',10);
 Writeln(P);            { Writes '         1'}
 RGrow(P,' ',20);
 Writeln(P);            { Writes '         1          '}
END;


StrStr

Declaration

PROCEDURE StrStr(VAR P : String;C:Char;Count:LONGINT);
PROCEDURE StrStr(VAR P : AnsiString;C:Char;Count:LONGINT);

Description

Fill string P with count characters C. Erases existing contents. (FillChar + patching of length information (SetLength for Ansistring, P[0] for pascal string)

The name comes from the old Basic procedure String$, which is often pronounced 'stringstring'.

Uses None

Example


VAR P : String;

BEGIN
 P:='1';
 StrStr(P,' ',10);
 Writeln(P);            { Writes '          '}
END;


Item range of procedures.

These are all three PASCAL procedures, but these ARE optimized for speed, so usable.

Declaration

    Pascal versions:

  1. PROCEDURE Item(VAR R: String; CONST S: String; CONST T: CHARSET; N: LONGINT);
  2. PROCEDURE Item(VAR R: String; CONST S: String; T: CHAR; N: LONGINT);
  3. PROCEDURE ItemS(VAR R: String; CONST S: String; CONST T: String; N: LONGINT);
  4. Ansistring versions:

  5. PROCEDURE Item(VAR R: AnsiString; CONST S: AnsiString; CONST T: CHARSET; N: LONGINT);
  6. PROCEDURE Item(VAR R: AnsiString; CONST S: AnsiString; T: CHAR; N: LONGINT);
  7. PROCEDURE ItemS(VAR R: AnsiString; CONST S: AnsiString; CONST T: AnsiString; N: LONGINT);

Description

These routines isolate strings separate by one (procedure 1) or more (2 and 3) separators. The original string is in Source, the isolated string will be written to Dest. N=0 gets the first string, N=1 the next etc.

If you ask for a high N, and it can't be found, the string is emptied.

Uses

Example


VAR Source,Dest : String;
    A :WORD;

BEGIN
 Source:=' hello1  hello2  hello3  hello4 ';
 FOR A :=0 TO 4 DO
  BEGIN
   Write(A,' ');
   Item(Dest,Source,' ',A);
   IF Length(Dest)=0 THEN
    Writeln('Empty')
   ELSE
    Writeln(Dest);
  END;
END;

Prints:
 0 hello1
 1 hello2
 2 hello3
 3 hello4
 4 Empty


GetBetween

This is a PASCAL procedure, but optimized for speed, so usable at a decent speed.

Declaration

FUNCTION GetBetween(Source:String;VAR Dest:String;C1,C2:CHAR):BOOLEAN;
FUNCTION GetBetween(Source:AnsiString;VAR Dest:AnsiString;C1,C2:CHAR):BOOLEAN;

Description

Copy chars between first occurance of C1 and C2 to Dest, return status (TRUE=success).

Using C1=C2 is allowed.

C2 characters before C1 are allowed and ignored. Only a C2 character AFTER C1 is detected. Existance of C1, but no character C2 AFTER C1 will cause the procedure to fail (return an empty string).

Uses

Example

VAR Source,Dest : String;

BEGIN
 Source:='0123456';
 GetBetween(Source,Dest,'1','4');
 Writeln(Dest);                       { Writes '23'}
END;


UpperCase

Declaration

PROCEDURE UpperCase(VAR S : String);
PROCEDURE UpperCase(VAR S : AnsiString);

Description

Uppercase all characters in string P. Only works for the normal (a..z) characters, not for international characters.

See also LowerCase

Example


VAR P : String;

BEGIN
 P:='abcde';
 UpperCase(P);
 Writeln(P);            {writes 'ABCDE'}
END;


LowerCase

Declaration

PROCEDURE LowerCase(VAR S : String);
PROCEDURE LowerCase(VAR S : AnsiString);

Description

Lowercase all characters in string P. Only works for the normal (A..Z) character, not for international characters.

See also UpperCase

Example


VAR P : String;

BEGIN
 GetMem(P,100);
 P:='ABCDE';
 LowerCase(P);
 Writeln(P);            {writes 'abcde'}
END;


CommaStr

Declaration

PROCEDURE Commastr(var S : String;sep:CHAR);
PROCEDURE Commastr(var S : AnsiString;sep:CHAR);

Description

Inserts separation character on each 3rd spot starting from the end of the string. e.g. 2123456789 -> 2,123,456,789

See also None

Example



VAR P : PChar;

BEGIN
 P:='12345678';
 CommaStr(P,'.');
 Writeln(P);            {writes '12.345.678'}
END;


ExpandTabs

Declaration

PROCEDURE ExpandTabs(CONST P : String;VAR P2:String;Tabsize:LONGINT);
PROCEDURE ExpandTabs(CONST P : AnsiString;VAR P2:AnsiString;Tabsize:LONGINT);

Description

Expands tabs in P to spaces, puts result in P2. (P untouched). Tabsize is the number characters between two tabs.

This procedure implements real tabbing, not simply replacing a hardtab with tabsize spaces. It doesn't implement smart tabbing(place tabstops dependant on text on a previous line).

This procedure is used to deal with tabs when reading textfiles. One ExpandTabs after each stringread (ReadLn) from the file, and forget all problems with tabs. If the identation doesn't matter, you can just use ReplaceChar (which would be faster) and replace each tab with a space.

See also CompressTabs

Example


VAR P : String;

BEGIN
 P:='1'+CHR(9)+2';
 ExpandTabs(P,P2,8);            {123456789}
 Writeln(P2);            {writes '1       2'}
END;


CompressTabs

Declaration

PROCEDURE CompressTabs(CONST Source :String;Var Dest:String;Tabsize:LONGINT);
PROCEDURE CompressTabs(CONST Source :AnsiString;Var Dest:AnsiString;Tabsize:LONGINT);

Description

Compress tabs to spaces, with variable tabsize. This procedure doesn't simply compress tabsize spaces to a hardtab, but implements tabbing like in an ordinary texteditor like q.exe (or joe).

Doesn't function well with hardtabs already in the input-string Source. In that case, run ExpandTabs first.

Source string is untouched. 'Normal' tabsize is 8, but specially in programmers editors, it is often 2 or 4

See also ExpandTabs

Example


VAR P,P2 : String;

BEGIN
 P:='1                      2                   3          4';
 CompressTabs(P,P2,8);
 Writeln('original length = ',Length(P),'  New length = ',Length(P2));
END;


BinaryToStr

Declaration

PROCEDURE BinaryToStr(VAR S : String;Value,Bits : CARDINAL);
PROCEDURE BinaryToStr(VAR S : AnsiString;Value,Bits : CARDINAL);

Description

Convert a number(Value) to a string (P) in binary representation, with a configurable number of bits(Bits), Bits is 0..32, and doesn't have to be a multiple of 8.

See also

Example

VAR P : String;

BEGIN
 BinaryToStr(P,$AAAA,15);
 Writeln(P);            {writes '010101010101010'}
END;


StrToBinary

Declaration

FUNCTION StrToBinary(CONST S : String;Bits : CARDINAL):CARDINAL;
FUNCTION StrToBinary(CONST S : AnsiString;Bits : CARDINAL):CARDINAL;

Description

Read first Bits digits from P (e.g. P:='0101010'), and return their binary value as a cardinal. Bits ranges from 0 to 32, though Bits=0 is useless (returns 0)

See also

Example

VAR P : String;

BEGIN
 P:='010101010101010';
 Writeln(StrToBinary(P,Length(P)); {writes '2AAA'}
END;


OctToStr

Declaration

PROCEDURE OctToStr (VAR S : String;Value,Digits : CARDINAL);
PROCEDURE OctToStr (VAR S : AnsiString;Value,Digits : CARDINAL);

Description

Convert a number(Value) to a string (P) in octal representation, with a configurable number of Digits (parameter Digits), Digits' range is 0..12.

See also

Example

VAR P : String;

BEGIN
 OctToStr(P,$AAAA,6);
 Writeln(P);            {writes '125252'}
END;


StrToOct

Declaration

FUNCTION StrToOct (CONST S : String;Digits: CARDINAL):CARDINAL;
FUNCTION StrToOct (CONST S : AnsiString;Digits: CARDINAL):CARDINAL;

Description

Read first Digits octal digits from P (e.g. P:='776'), and return their binary value as a cardinal. Digits ranges from 0 to 11, though Digits=0 is useless (returns 0)

See also

Example

VAR P : String;

BEGIN
 P:='125252';
 Writeln(StrToOct(P,Length(P))); {writes 'AAAA'}
END;


HexToStr

Declaration

PROCEDURE HexToStr (VAR S : String;Value,Digits : CARDINAL);
PROCEDURE HexToStr (VAR S : AnsiString;Value,Digits : CARDINAL);

Description

Convert a number(Value) to a string (P) in hexadecimal representation, with a configurable number of Digits (parmeter Digits), Digits' range is 0..12.

See also

Example

VAR P : String;

BEGIN
 HexToStr(P,$AAAA,6);
 Writeln(P);            {writes '00AAAA'}
END;


StrToHex

Declaration

FUNCTION StrToHex (CONST S : String;Digits: CARDINAL):CARDINAL;
FUNCTION StrToHex (CONST S : AnsiString;Digits: CARDINAL):CARDINAL;

Description

Read first Digits hexadecimal digits from P (e.g. P:='AAF'), and return their binary value as a cardinal. Digits ranges from 0 to 8, though Digits=0 is useless (returns 0)

See also

Example

VAR P : String;

BEGIN
 P:='ABCDEF';
 Writeln(StrToHex(P,Length(P))); {writes 'ABCDEF'}
END;