Since for the user the differences between Pascal and Ansistrings are quite small, I explain a certain procedure for both types in one paragraph.
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
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}
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;
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;
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;
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;
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;
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;
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;
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;
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
ExampleVAR P : String; BEGIN P:='text\ A A A A A '; Writeln(CharPos(P,'A')); {writes 7 } END;
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
ExampleVAR P : String; BEGIN P:='text\ A A A A A '; Writeln(RCharPos(P,'A')); {writes 15 } END;
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
ExampleVAR P : String; BEGIN P:='text\ A A A A A '; Writeln(NextCharPos(P,'A',8)); {writes 9} END;
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
ExampleVAR P : String; BEGIN P:='text\ A B A A A '; Writeln(NextCharPosSet(P,['A','B'],8)); {writes 9} END;
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
ExampleVAR P : String; BEGIN P:='text\ A A A A A '; Writeln(NextRCharPos(P,'A',14)); {writes 13 (the last but one A)} END;
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
ExampleVAR P : String; BEGIN P:='text\ A A A A A '; Writeln(CharPosSet(P,['A','\'])); {writes 5 } END;
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
ExampleVAR P : String; BEGIN P:=' 1 2 3 4 5'; StripDoubleChar(P,' '); Writeln(P); { Writes ' 1 2 3 4 5'} END;
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
ExampleVAR P : String; BEGIN P:='1'); RGrow(P,' ',10); Writeln(P); { Writes '1 '} END;
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
ExampleUses EPasStr; VAR P : String; BEGIN P:='1'; LGrow(P,' ',10); Writeln(P); { Writes ' 1'} RGrow(P,' ',20); Writeln(P); { Writes ' 1 '} END;
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;
These are all three PASCAL procedures, but these ARE optimized for speed, so usable.
Declaration
Ansistring versions:
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
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
ExampleVAR Source,Dest : String; BEGIN Source:='0123456'; GetBetween(Source,Dest,'1','4'); Writeln(Dest); { Writes '23'} END;
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;
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;
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;
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;
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;
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
ExampleVAR P : String; BEGIN BinaryToStr(P,$AAAA,15); Writeln(P); {writes '010101010101010'} END;
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
ExampleVAR P : String; BEGIN P:='010101010101010'; Writeln(StrToBinary(P,Length(P)); {writes '2AAA'} END;
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
ExampleVAR P : String; BEGIN OctToStr(P,$AAAA,6); Writeln(P); {writes '125252'} END;
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
ExampleVAR P : String; BEGIN P:='125252'; Writeln(StrToOct(P,Length(P))); {writes 'AAAA'} END;
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
ExampleVAR P : String; BEGIN HexToStr(P,$AAAA,6); Writeln(P); {writes '00AAAA'} END;
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
ExampleVAR P : String; BEGIN P:='ABCDEF'; Writeln(StrToHex(P,Length(P))); {writes 'ABCDEF'} END;