首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 2009 TStringBuilder 進階:Chars 索引器與 CopyTo 字元陣列複製技巧

     編輯:Delphi

字元級存取與批量複製:Chars[] 與 CopyTo

TStringBuilder 提供兩大字元級操作:

  • Chars[Index]:索引器,單字元讀寫 (0-based)
  • CopyTo:批量複製 緩衝區區段到字元陣列

這兩者構成高效字元操作基石,避免字串轉換開銷。

核心 API

成員類型參數/回傳說明
Chars[Index]索引器 (預設屬性)property Chars[Index: Integer]: Char read/write單字元存取,0-based
CopyTo方法procedure CopyTo(SourceIndex: Integer; Destination: TCharArray; DestinationIndex: Integer; Count: Integer)區段複製到字元陣列

完整實作程式碼


procedure TForm1.Button1Click(Sender: TObject); // CopyTo
var
  sb: TStringBuilder;
  arr: TCharArray;
  i: Integer;
begin
  sb := TStringBuilder.Create;
  try
    sb.Append('123456789');
    SetLength(arr, 9);
    for i := Low(arr) to High(arr) do arr[i] := '*'; // 初始化 '*'
    // 從 sb 索引 3 複製 5 字元 到 arr 索引 1
    sb.CopyTo(3, arr, 1, 5);
    ShowMessage(PChar(arr)); // 顯示 '*45678***'
  finally
    sb.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject); // Chars[]
var
  sb: TStringBuilder;
begin
  sb := TStringBuilder.Create('Delphi 2009');
  try
    ShowMessage(sb.Chars[0]);           // 'D' - 第一字元
    ShowMessage(sb.Chars[sb.Length - 1]); // '9' - 最後字元
    // 寫入範例
    sb.Chars[0] := 'd'; // 修改首字元為小寫
    ShowMessage(sb.ToString); // 'delphi 2009'
  finally
    sb.Free;
  end;
end;

CopyTo 參數詳解


sb.CopyTo(SourceIndex, Destination, DestinationIndex, Count);
參數說明範例值
SourceIndex來源緩衝區起始索引 (0-based)3 (第 4 字元 '4')
Destination目標字元陣列 (TCharArray = array of Char)arr (長度 9)
DestinationIndex目標陣列起始索引1 (arr[1] 開始放置)
Count複製字元數5 (複製 '45678')

結果:arr = ['*', '4', '5', '6', '7', '8', '*', '*', '*'] → PChar(arr) = '*45678***'

Chars[] 索引器特性

  • 0-based:Chars[0] 為首字元,Chars[Length-1] 為尾字元
  • 可讀寫:c := sb.Chars[i] / sb.Chars[i] := c
  • 預設屬性:sb[i] 等同 sb.Chars[i]
  • 邊界檢查:越界拋出 EArgumentOutOfRangeException
  • Unicode 安全:Char = WideChar (UTF-16 代碼單元)

進階應用場景

1. 高效字元統計:避免字串轉換


function CountChar(sb: TStringBuilder; Target: Char): Integer;
var i: Integer;
begin
  Result := 0;
  for i := 0 to sb.Length - 1 do
    if sb.Chars[i] = Target then Inc(Result);
end;

2. 原地修改:大小寫轉換、字元替換


procedure ToUpperInPlace(sb: TStringBuilder);
var i: Integer; c: Char;
begin
  for i := 0 to sb.Length - 1 do
  begin
    c := sb.Chars[i];
    if (c >= 'a') and (c <= 'z') then
      sb.Chars[i] := Char(Ord(c) - 32); // 簡易 ASCII 大寫
  end;
end;

procedure ReplaceCharInPlace(sb: TStringBuilder; OldChar, NewChar: Char);
var i: Integer;
begin
  for i := 0 to sb.Length - 1 do
    if sb.Chars[i] = OldChar then sb.Chars[i] := NewChar;
end;

3. 批量輸出到字元陣列:互操作非托管 API


procedure PassToCStyleAPI(sb: TStringBuilder);
var
  arr: TCharArray;
  len: Integer;
begin
  len := sb.Length;
  SetLength(arr, len + 1); // +1 給 null 結束符
  sb.CopyTo(0, arr, 0, len);
  arr[len] := #0; // 手動加 null
  // 呼叫 C API: MyCFunction(PChar(arr));
end;

4. 區段移動:實作 Insert/Remove 核心邏輯


procedure MoveGap(sb: TStringBuilder; FromIndex, ToIndex, Count: Integer);
var
  temp: TCharArray;
begin
  SetLength(temp, Count);
  sb.CopyTo(FromIndex, temp, 0, Count); // 複製到暫存
  // 這裡需配合內部緩衝區移動邏輯,實際用 Insert/Remove 方法更簡單
end;

Chars[] vs CopyTo 效能對比

操作Chars[] 迴圈CopyTo建議
單字元讀寫✅ O(1)❌用 Chars[]
連續區段複製❌ O(n) 逐個複製✅ O(n) 記憶體塊複製用 CopyTo
全緩衝區導出慢快 (單次 memcpy)用 CopyTo
非連續/條件式✅ 靈活❌用 Chars[]

最佳實務建議

  • 區段操作優先 CopyTo:底層呼叫 Move/CopyMemory,效能遠優於迴圈
  • 預分配目標陣列:SetLength(arr, Count) 避免重複分配
  • 注意 Unicode 代碼單元:Char = 2 字節,補字元 (Surrogate Pair) 佔 2 個 Char
  • CopyTo 不擴展目標陣列:確保 DestinationIndex + Count <= Length(Destination)
  • Chars[] 寫入會觸發緩衝區擴容檢查:大量寫入前考慮 EnsureCapacity

總結

Chars[] 提供隨機存取單字元能力,CopyTo 提供批量記憶體複製能力。兩者結合覆蓋從字元級解析、原地修改、統計分析到非托管互操作的完整需求。掌握 CopyTo(SourceIndex, Dest, DestIndex, Count) 參數語意,善用陣列預分配,即能發揮 TStringBuilder 高效字元緩衝區的最大效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved