Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sprintf in Delphi?

Does anyone know a 100% clone of the C/C++ printf for Delphi? Yes, I know the System.Format function, but it handles things a little different.

For example if you want to format 3 to "003" you need "%03d" in C, but "%.3d" in Delphi.

I have an application written in Delphi which has to be able to format numbers using C format strings, so do you know a snippet/library for that?

Thanks in advance!

like image 389
kroimon Avatar asked Mar 18 '10 17:03

kroimon


3 Answers

If you want to let the function look more Delphi friendly to the user, you could use the following:

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;
like image 68
Andreas Hausladen Avatar answered Oct 27 '22 07:10

Andreas Hausladen


It's not recommended to use (ws)printf since they are prone to buffer overflow, it would be better to use the safe variants (eg StringCchPrintF). It is already declared in the Jedi Apilib (JwaStrSafe).

like image 3
Remko Avatar answered Oct 27 '22 06:10

Remko


Well, I just found this one:

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer;
    cdecl; varargs; external 'msvcrt.dll';

It simply uses the original sprintf function from msvcrt.dll which can then be used like that:

procedure TForm1.Button1Click(Sender: TObject);
var s: AnsiString;
begin
  SetLength(s, 99);
  sprintf(PAnsiChar(s), '%d - %d', 1, 2);
  ShowMessage(S);
end;

I don't know if this is the best solution because it needs this external dll and you have to set the string's length manually which makes it prone to buffer overflows, but at least it works... Any better ideas?

like image 2
kroimon Avatar answered Oct 27 '22 06:10

kroimon