Кто-либо знает 100%-й клон C/C++ printf для Delphi? Да, я знаю Систему. Функция формата, но это обрабатывает вещи, немного отличающиеся.
Например, если Вы хотите к формату 3 к "003", Вам нужен "%03d" в C, но "%.3d" в Delphi.
Мне записали приложение в Delphi, который должен смочь отформатировать числа с помощью 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;
Если вы хотите, чтобы функция выглядела более дружественной к Delphi для пользователя, вы можете использовать следующее:
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, и вам нужно вручную установить длину строки, что делает ее склонной к переполнению буфера, но, по крайней мере, это работает ... Есть идеи лучше?