Есть ли аналог sscanf в Delphi?
не надо хотеть использовать говнопродукты типа дэлфи

это первая ссылка, возможно бальше есть и поопрятнее решения:
unit Scanf;
interface
uses SysUtils;
type
EFormatError = class(ExCeption);
function Sscanf(const s: string; const fmt : string;
const Pointers : array of Pointer) : Integer;
implementation
{ Sscanf parses an input string. The parameters ...
s - input string to parse
fmt - 'C' scanf-like format string to control parsing
%d - convert a Long Integer
%f - convert an Extended Float
%s - convert a string (delimited by spaces)
other char - increment s pointer past "other char"
space - does nothing
Pointers - array of pointers to have values assigned
result - number of variables actually assigned
for example with ...
Sscanf('Name. Bill Time. 7:32.77 Age. 8',
'. %s . %d:%f . %d', [@Name, @hrs, @min, @age]);
You get ...
Name = Bill hrs = 7 min = 32.77 age = 8 }
function Sscanf(const s: string; const fmt : string;
const Pointers : array of Pointer) : Integer;
var
i,j,n,m : integer;
s1 : string;
L : LongInt;
X : Extended;
function GetInt : Integer;
begin
s1 := '';
while (s[n] = ' ') and (Length(s) > n) do inc(n);
while (s[n] in ['0'..'9', '+', '-'])
and (Length(s) >= n) do begin
s1 := s1+s[n];
inc(n);
end;
Result := Length(s1);
end;
function GetFloat : Integer;
begin
s1 := '';
while (s[n] = ' ') and (Length(s) > n) do inc(n);
while (s[n] in ['0'..'9', '+', '-', '.', 'e', 'E'])
and (Length(s) >= n) do begin
s1 := s1+s[n];
inc(n);
end;
Result := Length(s1);
end;
function GetString : Integer;
begin
s1 := '';
while (s[n] = ' ') and (Length(s) > n) do inc(n);
while (s[n] <> ' ') and (Length(s) >= n) do
begin
s1 := s1+s[n];
inc(n);
end;
Result := Length(s1);
end;
function ScanStr(c : Char) : Boolean;
begin
while (s[n] <> c) and (Length(s) > n) do inc(n);
inc(n);
If (n <= Length(s then Result := True
else Result := False;
end;
function GetFmt : Integer;
begin
Result := -1;
while (TRUE) do begin
while (fmt[m] = ' ') and (Length(fmt) > m) do inc(m);
if (m >= Length(fmt then break;
if (fmt[m] = '%') then begin
inc(m);
case fmt[m] of
'd': Result := vtInteger;
'f': Result := vtExtended;
's': Result := vtString;
end;
inc(m);
break;
end;
if (ScanStr(fmt[m]) = False) then break;
inc(m);
end;
end;
begin
n := 1;
m := 1;
Result := 0;
for i := 0 to High(Pointers) do begin
j := GetFmt;
case j of
vtInteger : begin
if GetInt > 0 then begin
L := StrToInt(s1);
Move(L, Pointers[i]^, SizeOf(LongInt;
inc(Result);
end
else break;
end;
vtExtended : begin
if GetFloat > 0 then begin
X := StrToFloat(s1);
Move(X, Pointers[i]^, SizeOf(Extended;
inc(Result);
end
else break;
end;
vtString : begin
if GetString > 0 then begin
Move(s1, Pointers[i]^, Length(s1)+1);
inc(Result);
end
else break;
end;
else break;
end;
end;
end;
end.
надо было так:
Есть ли встроенный аналог...
Коль скоро люди пишут самопальные функции, значит нет.. печально.
да, и поинтеры - это беее..
PROCEDURE Parse (IN s: ARRAY OF CHAR; OUT x1, x2, x3: REAL; OUT c: ARRAY OF CHAR; OUT res: INTEGER);
VAR ch: CHAR; i: INTEGER;
PROCEDURE Get;
BEGIN
IF i < LEN(s) THEN ch := s[i]; INC(i)
ELSE ch := 0X
END
END Get;
PROCEDURE Real (OUT x: REAL);
VAR str: ARRAY 20 OF CHAR; i: INTEGER;
BEGIN
IF res # 0 THEN RETURN END;
i := 0;
IF (ch = '-') OR (ch = '+') THEN
str[i] := ch; INC(i); Get
END;
WHILE (ch >= '0') & (ch <= '9') DO
str[i] :=ch; INC(i); Get
END;
IF ch = '.' THEN str[i] := ch; INC(i); Get END;
WHILE (ch >= '0') & (ch <= '9') DO
str[i] :=ch; INC(i); Get
END;
IF i = 0 THEN res := 100
ELSE str[i] := 0X;
Strings.StringToReal(str, x, res)
END
END Real;
PROCEDURE Expect (ech: CHAR);
BEGIN
IF res = 0 THEN
IF ch = ech THEN Get ELSE res := 101 END
END
END Expect;
PROCEDURE SkipSpaces;
BEGIN
WHILE ch = ' ' DO Get END
END SkipSpaces;
PROCEDURE Comment (OUT c: ARRAY OF CHAR);
VAR i: INTEGER;
BEGIN
IF res # 0 THEN RETURN END;
i := 0;
WHILE ch # 0X DO
c[i] := ch; INC(i); Get
END;
c[i] := 0X
END Comment;
BEGIN
res := 0;
i := 0;
Get;
Real(x1);
Expect(',');
SkipSpaces;
Real(x2);
Expect(',');
SkipSpaces;
Real(x3);
SkipSpaces;
Expect(';');
SkipSpaces;
Comment(c)
END Parse;
А для более сложных случаев составляю грамматику EBNF и пользуюсь парсер-генератором.
Кстати, про парсеры.
Каким генератором пользуешься?
А # - это от кого? fpc?
да, и поинтеры - это беее..у джедаев не поинтеры.
я бы взял код джедаев
Жаль, что в дельфях механизм функций с переменным числом параметров реализован через Ж и то, в одну сторону (см. тот же Format)
на мой взгляд наоборот в дельфе он наилучшим образом сделан.
в шарпе, например.

Приведи, пожалуйста, объявление и использование функции с переменным числом параметров на дельфи.
procedure AddStuff( Const A: Array of Const );
Var i: Integer;
Begin
For i:= Low(A) to High(A) Do
With A[i] Do
Case VType of
vtExtended: Begin
{ add real number, all real formats are converted to
extended automatically }
End;
vtInteger: Begin
{ add integer number, all integer formats are converted
to LongInt automatically }
End;
vtObject: Begin
If VObject Is DArray Then
With DArray( VObject ) Do Begin
{ add array of doubles }
End
Else If VObject Is IArray Then
With IArray( VObject ) Do Begin
{ add array of integers }
End;
End;
End; { Case }
End; { AddStuff }
Вызов вроде такого: AddStuff([3, 2.5, "2", obj]);
Динамические массивы конкретного типа тоже существуют в дельфе
arr: array of integer;
Но вот это же один параметр, а не переменное число
результат один и тот же.
do([1, 2, 3]);вместо
do(1, 2, 3);
Радость есть.. Потому что работает именно так как надо. И есть возможность проконтролировать количество аргументов.
ОК
Массив кем и когда удаляется?
Да, про какой массив речь?
AddStuff([3, 2.5, "2", obj]);
и тип массива он сам что ли выводит? как компилятор понимает, какой тип массива сделать?
С точки зрения синтаксиса получается array of Variant.
этот массив существует, пока выполняется функция. после окончания выполнения - удаляется.
Оставить комментарий
yolki
вот про аналог sprintf знаю..шаз нужно распарсить такую строку:
В С делается просто...
как бы по-проще извернуться в паскале....