我想创建一个接收多个字符串作为参数的函数。
就像C的函数printf("Hello %s",name);
一样,但是我不想传递一个就绪数组,它就不可读了。
Edit1.text:=lang('Hello');
Edit2.text:=lang('Welcome to {1} guest',place);
Edit3.text:=lang('Hi {1}, is your {2} time in {3}','Victor','first','Disney');
输出应该是:
Hello
Welcome to Disney guest
Hi Victor is your first time in Disney
我如何创建function TForm1.lang(parameters:String):String;
,我做了一项研究,但我无法让它发挥作用。
我还需要访问参数[]和parameters.length。
我需要将我的应用程序转换为multilang。
答案 0 :(得分:4)
以下是如何执行此操作的示例函数:
function TForm1.lang(s: String; params: array of String): String;
var
i: Integer;
begin
for i := 0 to High(params) do
begin
ShowMessage(params[i]);
end;
end;
这样称呼:
lang('My format string', ['this', 'that']);
或者像这样:
var
b: String;
begin
b := 'this';
lang('My format string', [b, 'that']);
end;
答案 1 :(得分:3)
不确定你的意思是不可读
DoSomething(['Param1','Param2']);
代表
procedure DoSomething(args : Array of String);
Var
Index : Integer;
Begin
for index := Low(args) to High(args) Do
ShowMessage(args[Index]);
End;
似乎对我好。当然如果你想从delphi外面调用它,那你就有问题了。
快速修复只是传入一个分隔的字符串,然后用户TStringList将其拆分。
你可以编写一个wee函数来做到这一点,不要忘记在完成后释放它。
答案 2 :(得分:1)
您可以使用SysUtils.Format修复所有三个示例:
Edit1.text := format('%s',['Hello']));
Edit1.text := format('Welcome to %s guest',[place]));
Edit1.text := format('Hi %s, is your %s time in %s',['Victor','first','Disney']));
我个人觉得它很可读。如果您可以从基本的sysutils函数中获得所需的内容,那么您应该认真考虑这样做,而不是编写自己的版本。另一方面,您可能需要更复杂的功能,而这些功能并未在您的问题中显示。如果是这种情况,我认为paulsm4建议使用字符串列表似乎是一个很好的方法。
答案 3 :(得分:1)
Delphi不支持使用vararg
创建函数 - 样式参数与printf()
完全相同。它仅支持从外部库中消耗此类函数。最接近Delphi的支持使用可变参数列表创建函数的方法是使用“开放数组”参数,就像SysUtils.Format()
使用的那样。
答案 4 :(得分:0)
正如Tony上面提到的,我还建议使用一个删除字符串。除了,不仅仅是消除,而是使用更多的解析技术。如果我理解正确,你正在进行格式化的这个函数不应该在参数中包含一个数组,但从技术上讲,这并不意味着我们不能在任何地方使用数组(数组非常适合用于这个场景快速表现)。
此方法几乎可以在参数中传递任何内容,包括分隔符,而不会影响输出。想法是做A)参数字符串的大小,B)大小和参数之间的分隔符,以及C)参数字符串......并重复......
const
MY_DELIM = '|'; //Define a deliminator
type
TStringArray = array of String;
/////////////////////////////////
//Convert an array of string to a single parsable string
// (Will be the first step before calling your format function)
function MakeParams(const Params: array of String): String;
var
X: Integer;
S: String;
begin
Result:= '';
for X:= 0 to Length(Params)-1 do begin
S:= Params[X];
Result:= Result + IntToStr(Length(S)) + MY_DELIM + S;
end;
end;
//Convert a single parsable string to an array of string
// (Will be called inside your format function to decode)
// This is more or less called parsing
function ExtractParams(const Params: String): TStringArray;
var
S: String; //Used for temporary parsing
T: String; //Used for copying temporary data from string
P: Integer; //Used for finding positions
C: Integer; //Used for keeping track of param count
Z: Integer; //Used for keeping track of parameter sizes
begin
S:= Params; //Because we'll be using 'Delete' command
C:= 0; //Set count to 0 to start
SetLength(Result, 0); //Prepare result array to 0 parameters
while Length(S) > 0 do begin //Do loop until nothing's left
P:= Pos(MY_DELIM, S); //Get position of next deliminator
if P > 1 then begin //If deliminator was found...
C:= C + 1; //We have a new parameter
SetLength(Result, C); //Set array length to new parameter count
T:= Copy(S, 1, P-1); //Get all text up to where deliminator was found
Delete(S, 1, P); //Delete what we just copied, including deliminator
Z:= StrToIntDef(T, 0); //Convert T:String to Z: Integer for size of parameter
T:= Copy(S, 1, Z); //Get all text up to 'Z' (size of parameter)
Delete(S, 1, Z); //Delete what we just copied
Result[C-1]:= T; //Assign the new parameter to end of array result
end else begin //If deliminator was NOT found...
S:= ''; //Clear S to exit loop (possible bad format if this happens)
end;
end;
end;
//Main formatting routine
function MyFormat(const Input: String; const Params: String): String;
var
A: TStringArray;
X: Integer;
S: String;
P: Integer;
R: String;
begin
R:= Input;
A:= ExtractParams(Params);
//At this point, A contains all the parameters parsed from 'Params'
for X:= 0 to Length(A)-1 do begin
S:= A[X];
P:= Pos('%s', R);
if P > 0 then begin
Delete(R, P, 2);
Insert(S, R, P);
end;
end;
Result:= R;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Pars: String;
begin
Pars:= MakeParams(['this', 'that', 'something else']);
Edit1.Text:= MyFormat('%s is %s but not %s', Pars);
end;
答案 5 :(得分:-1)
您可能知道,SysUtils.Format()通过使用集合来实现“varargs”。
但是,在您的情况下,为什么不直接传递TStringList?该功能只需检查“list.Count”。瞧 - 你已经完成了!