سؤال
هل يعرف أي شخص استنساخ 100 ٪ من C/C ++ printf لدلفي؟ نعم ، أنا أعرف النظام.شكل وظيفة ، لكنها تعالج الأشياء مختلفة بعض الشيء.
على سبيل المثال ، إذا كنت ترغب في التنسيق 3 إلى "003" ، فأنت بحاجة إلى "٪ 03D" في C ، ولكن "٪ .3d" في دلفي.
لدي تطبيق مكتوب في دلفي يجب أن يكون قادرًا على تنسيق الأرقام باستخدام سلاسل تنسيق C ، هل تعرف مقتطف/مكتبة لذلك؟
شكرا مقدما!
المحلول
يمكنك استخدام وظيفة WSPRINTF () من Windows.PAS. لسوء الحظ ، لم يتم الإعلان عن هذه الوظيفة بشكل صحيح في Windows.pas ، لذا إليك إعادة تجديد:
function wsprintf(Output: PChar; Format: PChar): Integer; cdecl; varargs;
external user32 name {$IFDEF UNICODE}'wsprintfW'{$ELSE}'wsprintfA'{$ENDIF};
procedure TForm1.FormCreate(Sender: TObject);
var
S: String;
begin
SetLength(S, 1024); // wsprintf can work only with max. 1024 characters
SetLength(S, wsprintf(PChar(S), '%s %03d', 'Hallo', 3));
end;
نصائح أخرى
إذا كنت ترغب في ترك الوظيفة تبدو أكثر ودية للمستخدم ، فيمكنك استخدام ما يلي:
function _FormatC(const Format: string): string; cdecl;
const
StackSlotSize = SizeOf(Pointer);
var
Args: va_list;
Buffer: array[0..1024] of Char;
begin
// va_start(Args, Format)
Args := va_list(PAnsiChar(@Format) + ((SizeOf(Format) + StackSlotSize - 1) and not (StackSlotSize - 1)));
SetString(Result, Buffer, wvsprintf(Buffer, PChar(Format), Args));
end;
const // allows us to use "varargs" in Delphi
FormatC: function(const Format: string): string; cdecl varargs = _FormatC;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(FormatC('%s %03d', 'Hallo', 3));
end;
لا ينصح باستخدام (WS) printf لأنها عرضة للتخزين المؤقت ، سيكون من الأفضل استخدام المتغيرات الآمنة (على سبيل المثال StringCchprintf). تم إعلانه بالفعل في Jedi Apilib (Jwastrsafe).
حسنًا ، لقد وجدت هذا:
function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer;
cdecl; varargs; external 'msvcrt.dll';
إنه ببساطة يستخدم وظيفة Sprintf الأصلية من msvcrt.dll
التي يمكن استخدامها بعد ذلك:
procedure TForm1.Button1Click(Sender: TObject);
var s: AnsiString;
begin
SetLength(s, 99);
sprintf(PAnsiChar(s), '%d - %d', 1, 2);
ShowMessage(S);
end;
لا أعرف ما إذا كان هذا هو الحل الأفضل لأنه يحتاج إلى هذا DLL الخارجي وعليك ضبط طول السلسلة يدويًا مما يجعله عرضة للتدفق العازلة ، ولكن على الأقل يعمل ... أي أفكار أفضل؟
المزيد من النهج النظيف دون صب النوع غير الضروري
function sprintf(CharBuf: PChar; const Format: PAnsiChar): Integer;
cdecl; varargs; external 'msvcrt.dll';
procedure TForm1.Button1Click(Sender: TObject);
var CharBuf: PChar;
begin
CharBuf:=StrAlloc (99);
sprintf(CharBuf, 'two numbers %d - %d', 1, 2);
ShowMessage(CharBuf);
StrDispose(CharBuf);
end;
إذا صادفك التجميع المتقاطع لتطبيق Windows CE. استخدم coredll.dll بدلاً من msvcrt.dll