Frage

Kennt jemand einen 100% igen Klon des C/C ++? printf Für Delphi? Ja, ich kenne das System.Format Funktion, aber es behandelt die Dinge ein wenig anders.

Wenn Sie beispielsweise 3 auf "003" formatieren möchten, brauchen Sie in C "%03d", aber "%.3d" in Delphi.

Ich habe eine Anwendung in Delphi geschrieben, die in der Lage sein muss, Zahlen mit C -Format -Zeichenfolgen zu formatieren. Kennen Sie dafür ein Ausschnitt/eine Bibliothek?

Danke im Voraus!

War es hilfreich?

Lösung

Sie können die WSPRINTF () -Funktion von Windows.pas verwenden. Leider wird diese Funktion in den Windows.pas nicht korrekt deklariert. Hier finden Sie eine erneute Redaktion:

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;

Andere Tipps

Wenn Sie die Funktion für den Benutzer delphi freundlicher aussehen möchten, können Sie Folgendes verwenden:

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;

Es wird nicht empfohlen, Printf (WS) zu verwenden, da sie anfällig für Pufferüberlauf sind. Es wäre besser, die sicheren Varianten zu verwenden (z. B. StringCChPrintf). Es wird bereits im Jedi -Apilib (JWastrsafe) deklariert.

Nun, ich habe gerade das gefunden:

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

Es verwendet einfach die ursprüngliche Sprintf -Funktion von msvcrt.dll was dann so verwendet werden kann:

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

Ich weiß nicht, ob dies die beste Lösung ist, da sie diese externe DLL benötigt und Sie die Länge der Saite manuell einstellen müssen, was es anfällig für Pufferüberläufe macht, aber zumindest funktioniert es ... irgendwelche besseren Ideen?

Weiterer sauberer Ansatz ohne unnötiges Typ Casting

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;

Wenn Sie zufällig für die Windows CE -App kompilieren. Verwenden Sie coredll.dll anstelle von msvcrt.dll

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top