6

Delphi 用の C/C++ printfの 100% クローンを知っている人はいますか? はい、私はシステムを知っています。フォーマット関数ですが、処理が少し異なります。

たとえば、3 を "003" にフォーマットする場合、C では "%03d" が必要ですが、Delphi では "%.3d" が必要です。

C フォーマット文字列を使用して数値をフォーマットできるようにする必要がある Delphi で記述されたアプリケーションがあります。そのためのスニペット/ライブラリを知っていますか?

前もって感謝します!

4

5 に答える 5

16

Windows.pas の wsprintf() 関数を使用できます。残念ながら、この関数は 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;
于 2010-03-18T17:42:36.880 に答える
9

関数をユーザーにとってより 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;
于 2010-03-18T17:57:26.990 に答える
3

(ws)printf はバッファ オーバーフローが発生しやすいため、使用することはお勧めしません。安全なバリアント ( StringCchPrintF など) を使用することをお勧めします。これは、Jedi Apilib (JwaStrSafe) で既に宣言されています。

于 2010-03-19T07:24:16.703 に答える
2

さて、私はこれを見つけました:

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が必要であり、文字列の長さを手動で設定する必要があるため、これが最善の解決策であるかどうかはわかりませんが、バッファオーバーフローが発生しやすくなりますが、少なくとも機能します...もっと良いアイデアはありますか?

于 2010-03-18T17:46:32.993 に答える
0

不要な型キャストのない、よりクリーンなアプローチ

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 アプリのクロス コンパイルが発生した場合。msvcrt.dll の代わりに coredll.dll を使用する

于 2013-10-07T07:09:32.153 に答える