[Back to ENTRY SWAG index] [Back to Main SWAG index] [Original]
{
>Format is really a good function for use on output and it corresponds roughly
>to the printf function in C, but I really need the corresponding input
>function as well (scanf etc)
>
>does anyone know of such a function? I would hate to spend the time
>reinventing the wheel, when I could be concentrating on other things.
Here's my implementation of scanf:
--------------------------------------------------------------------------}
function sscanf(Input, Format : PChar; var ArgList) : PChar;
type
WordPtr = ^word;
LongPtr = ^longint;
PCharPtr = ^PChar;
var
DelimPos : PChar;
ArgPtr : PChar;
n : longint;
FmtCmd : char;
code : integer;
LongCmd : boolean;
LenStr : string[8];
MaxLen : integer;
begin
sscanf := nil;
ArgPtr := addr(ArgList);
if (Format = nil) then Exit;
while (Format^ <> #0) do begin
if (Input = nil) or (Input^ = #0) then Exit; { ***ERROR }
if Format^ = '%' then begin
inc(Format);
FmtCmd := Format^;
if FmtCmd in ['0'..'9'] then begin
LenStr := '';
repeat
LenStr := LenStr + FmtCmd;
inc(Format);
FmtCmd := Format^;
until not (FmtCmd in ['0'..'9']);
if LenStr <> '' then begin
Val(LenStr, MaxLen, code);
if code <> 0 then Exit;
end;
end else
MaxLen := $7FFF;
if FmtCmd = 'l' then begin
LongCmd := true;
inc(Format);
FmtCmd := Format^;
end else
LongCmd := false;
case FmtCmd of
'c' : begin
ArgPtr^ := Input^;
inc(ArgPtr, 2);
end;
'd','i','u','s','*' : begin
{ look for delimiter }
DelimPos := StrScan(Input, (Format+1)^);
if DelimPos <> nil then begin
if (DelimPos-Input > MaxLen) then Exit;
DelimPos^ := #0; { zero delimiter }
end;
if FmtCmd = 's' then begin
if PCharPtr(ArgPtr)^ = nil then { if dest. string is NIL }
PCharPtr(ArgPtr)^ := StrNew(Input) { then allocate a new one }
else
StrCopy(PCharPtr(ArgPtr)^, Input); { else copy to dest buffer }
end else
if FmtCmd <> '*' then
Val(Input, n, code);
if DelimPos <> nil then DelimPos^ := (Format+1)^; { set it back }
case FmtCmd of
's' : inc(ArgPtr, 4);
'*' : ; { dummy }
else
if code <> 0 then Exit; { could not convert }
if LongCmd then begin
LongPtr(ArgPtr)^ := n;
inc(ArgPtr, 4);
end else begin
WordPtr(ArgPtr)^ := LongRec(n).Lo;
inc(ArgPtr, 2);
end;
end;
Input := DelimPos; { move input pointer to delimiter }
end;
else
Exit;
end;
inc(Format);
end else begin
if Input^ <> Format^ then Exit;
inc(Format);
inc(Input);
end;
end;
sscanf := Input;
end;
[Back to ENTRY SWAG index] [Back to Main SWAG index] [Original]