Delphi格式字符串 - 宽度和精度值的限制?

tim*_*11g 2 delphi formatting delphi-7 number-formatting

本声明(在Delphi 7中)

writeln(logfile,format('%16.16d ',[FileInfo.size])+full_name);
Run Code Online (Sandbox Code Playgroud)

得到这个输出

0000000021239384 C:\DATA\DELPHI\sxf_archive10-13.zip
Run Code Online (Sandbox Code Playgroud)

这个说法

writeln(logfile,format('%17.17d ',[FileInfo.size])+full_name);
Run Code Online (Sandbox Code Playgroud)

得到这个输出

         21239384 C:\DATA\DELPHI\sxf_archive10-13.zip
Run Code Online (Sandbox Code Playgroud)

当精度说明符大于16时,带前导零的填充变为前导空格.帮助说"如果格式字符串包含精度说明符,则表示结果字符串必须至少包含指定的位数;如果值数字较少,结果字符串左边用零填充."

是否有另一种方法来格式化带有前导零的20个字符的整数?

Rem*_*eau 5

一个Integer值的精度限制为最多16位.如果指定的Precision大于16,则使用0代替.这不是一个错误,它是硬编码的逻辑,并没有记录.

有两种方法可以解决这个问题:

  1. 用一个Int64而不是一个Integer.精度Int64最多为32位:

    WriteLn(logfile, Format('%20.20d %s', [Int64(FileInfo.Size), full_name]);
    
    Run Code Online (Sandbox Code Playgroud)

    注意:在Delphi 2006及更高版本中,TSearchRec.Size是一个Int64.在早期版本中,它是一个Integer替代,因此限制为2GB.如果您需要在早期版本中处理大于2GB的文件大小,则可以从该TSearchRec.FindData字段获取完整的64位大小:

    var
      FileSize: ULARGE_INTEGER;
    begin
      FileSize.LowPart := FileInfo.FindData.nFileSizeLow;
      FileSize.HighPart := FileInfo.FindData.nFileSizeHigh:
      WriteLn(logfile, Format('%20.20d %s', [FileSize.QuadPart, full_name]);
    end;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 转换为Integer没有任何前导零的字符串,然后使用StringOfChar()前置任何所需的零:

    s := IntToStr(FileInfo.Size);
    if Length(s) < 20 then
      s := StringOfChar('0', 20-Length(s)) + s;
    WriteLn(logfile, s + ' ' + full_name);
    
    Run Code Online (Sandbox Code Playgroud)