sprintf в Delphi?

Кто-либо знает 100%-й клон C/C++ printf для Delphi? Да, я знаю Систему. Функция формата, но это обрабатывает вещи, немного отличающиеся.

Например, если Вы хотите к формату 3 к "003", Вам нужен "%03d" в C, но "%.3d" в Delphi.

Мне записали приложение в Delphi, который должен смочь отформатировать числа с помощью C строки формата, Вы знаете отрывок/библиотеку для этого?

Заранее спасибо!

5
задан kroimon 18 March 2010 в 18:10
поделиться

4 ответа

Вы можете использовать функцию 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;
14
ответ дан 18 December 2019 в 06:02
поделиться

Если вы хотите, чтобы функция выглядела более дружественной к 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;
9
ответ дан 18 December 2019 в 06:02
поделиться

Не рекомендуется использовать (ws) printf, поскольку они склонны к переполнению буфера, лучше использовать безопасные варианты (например, StringCchPrintF ). Это уже заявлено в Jedi Apilib (JwaStrSafe).

3
ответ дан 18 December 2019 в 06:02
поделиться

Я только что нашел вот это:

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, и вам нужно вручную установить длину строки, что делает ее склонной к переполнению буфера, но, по крайней мере, это работает ... Есть идеи лучше?

1
ответ дан 18 December 2019 в 06:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: