亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 字符串操作 .txt

?? delphi知識收集 我個人的小小收集
?? TXT
字號:
字符串操作 
--------------------------------------------------------------------------------
作者:不詳  來源于:不詳  發(fā)布時間:2005-2-13 15:54:20 
Delphi 中字符串的操作很簡單,但幕后情況卻相當(dāng)復(fù)雜。Pascal 傳統(tǒng)的字符串操作方法與Windows 不同,Windows吸取了C語言的字符串操作方法。32位Delphi中增加了長字符串類型,該類型功能強(qiáng)大,是Delphi 確省的字符串類型。

字符串類型 
在Borland公司的Turbo Pascal和16位Delphi中,傳統(tǒng)的字符串類型是一個字符序列,序列的頭部是一個長度字節(jié),指示當(dāng)前字符串的長度。由于只用一個字節(jié)來表示字符串的長度,所以字符串不能超過255個字符。這一長度限制為字符串操作帶來不便,因為每個字符串必須定長(確省最大值為255),當(dāng)然你也可以聲明更短的字符串以節(jié)約存儲空間。

字符串類型與數(shù)組類型相似。實際上一個字符串差不多就是一個字符類型的數(shù)組,因為用[]符號,你就能訪問字符串中的字符,這一事實充分說明了上述觀點。

為克服傳統(tǒng)Pascal 字符串的局限性,32位Delphi增加了對長字符串的支持。這樣共有三種字符串類型:

ShortString 短字符串類型也就是前面所述的傳統(tǒng) Pascal 字符串類型。這類字符串最多只能有255個字符,與16位Delphi中的字符串相同。短字符串中的每個字符都屬于ANSIChar 類型(標(biāo)準(zhǔn)字符類型)。 
ANSIString長字符串類型就是新增的可變長字符串類型。這類字符串的內(nèi)存動態(tài)分配,引用計數(shù),并使用了更新前拷貝(copy--on-write)技術(shù)。這類字符串長度沒有限制(可以存儲多達(dá)20億個字符!),其字符類型也是ANSIChar 類型。 
WideString 長字符串類型與ANSIString 類型相似,只是它基于WideChar 字符類型,WideChar 字符為雙字節(jié)Unicode 字符。 
使用長字符串 
如果只簡單地用String定義字符串,那么該字符串可能是短字符串也可能是ANSI長字符串,這取決于$H 編譯指令的值,$H+(確省)代表長字符串(ANSIString 類型)。長字符串是Delphi 庫中控件使用的字符串。

Delphi 長字符串基于引用計數(shù)機(jī)制,通過引用計數(shù)追蹤內(nèi)存中引用同一字符串的字符串變量,當(dāng)字符串不再使用時,也就是說引用計數(shù)為零時,釋放內(nèi)存。

如果你要增加字符串的長度,而該字符串鄰近又沒有空閑的內(nèi)存,即在同一存儲單元字符串已沒有擴(kuò)展的余地,這時字符串必須被完整地拷貝到另一個存儲單元。當(dāng)這種情況發(fā)生時,Delphi運(yùn)行時間支持程序會以完全透明的方式為字符串重新分配內(nèi)存。為了有效地分配所需的存儲空間,你可以用SetLength 過程設(shè)定字符串的最大長度值:

SetLength (String1, 200);
SetLength 過程只是完成一個內(nèi)存請求,并沒有實際分配內(nèi)存。它只是把將來所需的內(nèi)存預(yù)留出來,實際上并沒有使用這段內(nèi)存。這一技術(shù)源于Windows 操作系統(tǒng),現(xiàn)被Delphi用來動態(tài)分配內(nèi)存。例如,當(dāng)你請求一個很大的數(shù)組時,系統(tǒng)會將數(shù)組內(nèi)存預(yù)留出來,但并沒有把內(nèi)存分配給數(shù)組。

一般不需要設(shè)置字符串的長度,不過當(dāng)需要把長字符串作為參數(shù)傳遞給API 函數(shù)時(經(jīng)過類型轉(zhuǎn)換后),你必須用SetLength 為該字符串預(yù)留內(nèi)存空間,這一點我會在后面進(jìn)行說明。

看一看內(nèi)存中的字符串 
為了幫你更好地理解字符串的內(nèi)存管理細(xì)節(jié),我寫了一個簡例StrRef 。在程序中我聲明了兩個全程字符串:Str1 和 Str2,當(dāng)按下第一個按鈕時,程序把一個字符串常量賦給第一個變量,然后把第一個變量賦給第二個:

Str1 := 'Hello';
Str2 := Str1;
除了字符串操作外,程序還用下面的StringStatus 函數(shù)在一個列表框中顯示字符串的內(nèi)部狀態(tài):

function StringStatus (const Str: string): string;
begin
  Result := 'Address: ' + IntToStr (Integer (Str)) +
    ', Length: ' + IntToStr (Length (Str)) + 
    ', References: ' + IntToStr (PInteger (Integer (Str) - 8)^) +
    ', Value: ' + Str;
end;
在StringStatus 函數(shù)中,用常量參數(shù)傳遞字符串至關(guān)重要。用拷貝方式(值參)傳遞會引起副作用,因為函數(shù)執(zhí)行過程中會產(chǎn)生一個對字符串的額外引用;與此相反,通過引用(var)或常量(const)參數(shù)傳遞不會產(chǎn)生這種情況。由于本例不希望字符串被修改,因此選用常量參數(shù)。

為獲取字符串內(nèi)存地址(有利于識別串的實際內(nèi)容也有助于觀察兩個不同的串變量是否引用了同一內(nèi)存區(qū)),我通過類型映射把字符串類型強(qiáng)行轉(zhuǎn)換為整型。字符串實際上是引用,也就是指針:字符串變量保存的是字符串的實際內(nèi)存地址。

為了提取引用計數(shù)信息,我利用了一個鮮為人知的事實:即字符串長度和引用計數(shù)信息實際上保存在字符串中, 位于實際內(nèi)容和字符串變量所指的內(nèi)存位置之前,其負(fù)偏移量對字符串長度來說是-4(用Length 函數(shù)很容易得到這個值),對引用記數(shù)來說是-8。

不過必須記住,以上關(guān)于偏移量的內(nèi)部信息在未來的Delphi版本中可能會變,沒有寫入正式Delphi文檔的特性很難保證將來不變。

通過運(yùn)行這個例子,你會看到兩個串內(nèi)容相同、內(nèi)存位置相同、引用記數(shù)為2,如圖7.1中列表框上部所示。現(xiàn)在,如果你改變其中一個字符串的值,那么更新后字符串的內(nèi)存地址將會改變。這是copy-on-write技術(shù)的結(jié)果。

圖 7.1: 例StrRef顯示兩個串的內(nèi)部狀態(tài),包括當(dāng)前引用計數(shù) 

 

第二個按鈕(Change)的OnClick 事件代碼如下,結(jié)果如圖7.1列表框第二部分所示:

procedure TFormStrRef.BtnChangeClick(Sender: TObject);
begin
  Str1 [2] := 'a';
  ListBox1.Items.Add ('Str1 [2] := ''a''');
  ListBox1.Items.Add ('Str1 - ' + StringStatus (Str1));
  ListBox1.Items.Add ('Str2 - ' + StringStatus (Str2));
end;
注意,BtnChangeClick 只能在執(zhí)行完BtnAssignClick 后才能執(zhí)行。為此,程序啟動后第二個按鈕不能用(按鈕的Enabled 屬性設(shè)成False);第一個方法結(jié)束后激活第二個按鈕。你可以自由地擴(kuò)展這個例子,用StringStatus 函數(shù)探究其它情況下長字符串的特性。

Delphi 字符串與 Windows PChar字符串 
長字符串為零終止串,這意味著長字符串完全與Windows使用的C語言零終止串兼容,這給長字符串使用帶來了便利。一個零終止串是一個字符序列,該序列以一個零字節(jié)(或null)結(jié)尾。零終止串在Delphi中可用下標(biāo)從零開始的字符數(shù)組表示,C語言就是用這種數(shù)組類型定義字符串,因此零終止字符數(shù)組在Windows API 函數(shù)(基于C語言)中很常見。由于Pascal長字符串與C語言的零終止字符串完全兼容,因此當(dāng)需要把字符串傳遞給Windows API 函數(shù)時,你可以直接把長字符串映射為PChar 類型。

下例把一個窗體的標(biāo)題拷貝給PChar 字符串(用API 函數(shù)GetWindowText),然后再把它拷貝給按鈕的Caption 屬性,代碼如下:

procedure TForm1.Button1Click (Sender: TObject);
var
  S1: String;
begin
  SetLength (S1, 100);
  GetWindowText (Handle, PChar (S1), Length (S1));
  Button1.Caption := S1;
end;
你可以在例LongStr 中找到這段代碼。注意:代碼中用SetLength函數(shù)為字符串分配內(nèi)存,假如內(nèi)存分配失敗,那么程序就會崩潰;如果你直接用PChar 類型傳遞值(而不是象以以上代碼那樣接受一個值),那么代碼會很簡單,因為不需要定義臨時字符串,也不需要初始化串。下面代碼把一個Label(標(biāo)簽)控件的Caption 屬性作為參數(shù)傳遞給了API函數(shù),只需要簡單地把屬性值映射為PChar類型:

SetWindowText (Handle, PChar (Label1.Caption));
當(dāng)需要把WideString 映射為Windows兼容類型時,你必須用PWideChar 代替PChar進(jìn)行轉(zhuǎn)換,WideString常用于OLE和 COM 程序。

剛才展現(xiàn)了長字符串的優(yōu)點,現(xiàn)在談?wù)勊谋锥恕.?dāng)你把長字符串轉(zhuǎn)換為PChar 類型時可能會引發(fā)一些問題,問題根本在于:轉(zhuǎn)換以后字符串及其內(nèi)容將由你來負(fù)責(zé),Delphi 不再管了。現(xiàn)在把上面Button1Click代碼稍作修改:

procedure TForm1.Button2Click(Sender: TObject);
var
  S1: String;
begin
  SetLength (S1, 100);
  GetWindowText (Handle, PChar (S1), Length (S1));
  S1 := S1 + ' is the title'; // this won't work
  Button1.Caption := S1;
end;
程序編譯通過,但執(zhí)行結(jié)果會令你驚訝,因為按鈕的標(biāo)題并沒變,所加的常量字符串沒有添加到按鈕標(biāo)題中。問題原因是Windows寫字符串時(在GetWindowText API調(diào)用中),Windows 沒有正確設(shè)置Pascal 長字符串的長度。Delphi 仍可以輸出該字符串,并能通過零終止符判斷字符串何時結(jié)束,但是如果你在零終止符后添加更多的字符,那么這些字符將被忽略。

怎么解決這個問題呢?解決方法是告訴系統(tǒng)把GetWindowText API函數(shù)返回的字符串再轉(zhuǎn)換成Pascal字符串。然而,如果你用以下代碼:

S1 := String (S1);
Delphi 系統(tǒng)將不予理睬,因為把一種類型轉(zhuǎn)換為它自己的類型是無用的操作。為獲得正確的Pascal 長字符串,需要你把字符串重新映射為一個PChar 字符串,然后讓Delphi 再把它轉(zhuǎn)回到字符串:

S1 := String (PChar (S1));
實際上,你可以跳過字符串轉(zhuǎn)換(S1 := PChar (S1));, 因為在Delphi中Pchar轉(zhuǎn)換到string是自動執(zhí)行的,最終代碼如下:

procedure TForm1.Button3Click(Sender: TObject);
var
  S1: String;
begin
  SetLength (S1, 100);
  GetWindowText (Handle, PChar (S1), Length (S1));
  S1 := String (PChar (S1));
  S1 := S1 + ' is the title';
  Button3.Caption := S1;
end;
另一個辦法是用PChar 字符串的長度重新設(shè)定Delphi 字符串長度,可以這樣寫:

SetLength (S1, StrLen (PChar (S1)));
在例LongStr中你可以看到三種方法的結(jié)果,分別由三個按鈕執(zhí)行。如果只想訪問窗體標(biāo)題,僅需要用到窗體對象本身的Caption 屬性,沒有必要寫這段迷糊人的代碼,這段代碼只是用來說明字符串轉(zhuǎn)換問題。當(dāng)調(diào)用Windows API 函數(shù)時會遇到這種實際問題,那時你就不得不考慮這一復(fù)雜情況了。

格式化字符串 
使用加號(+)操作符和轉(zhuǎn)換函數(shù)(如IntToStr),你確實能把已有值組合成字符串,不過另有一種方法能格式化數(shù)字、貨幣值和其他字符串,這就是功能強(qiáng)大的Format 函數(shù)及其一族。

Format 函數(shù)參數(shù)包括:一個基本文本字符串、一些占位符(通常由%符號標(biāo)出)和一個數(shù)值數(shù)組,數(shù)組中每個值對應(yīng)一個占位符。例如,把兩個數(shù)字格式化為字符串的代碼如下:

Format ('First %d, Second %d', [n1, n2]);
其中n1和n2是兩個整數(shù)值,第一個占位符由第一個值替代,第二個占位符由第二個值替代,以此類推。如果占位符輸出類型(由%符號后面的字母表示)與對應(yīng)的參數(shù)類型不匹配,將產(chǎn)生一個運(yùn)行時間錯誤,因此設(shè)置編譯時間類型檢查會有利于Format 函數(shù)的使用。

除了%d外,F(xiàn)ormat 函數(shù)還定義了許多占位符,見表7.1。這些占位符定義了相應(yīng)數(shù)據(jù)類型的默認(rèn)輸出,你可以用更深一層的格式化約束改變默認(rèn)輸出,例如一個寬度約束決定了輸出中的字符個數(shù),而精度約束決定了小數(shù)點的位數(shù)。例如

Format ('%8d', [n1]);
該句把數(shù)字n1轉(zhuǎn)換成有8個字符的字符串,并通過填充空白使文本右對齊,左對齊用減號(-) 。

表 7.1: Format函數(shù)的占位符 

  占位符 說明 
d (decimal) 將整型值轉(zhuǎn)換為十進(jìn)制數(shù)字字符串 
x (hexadecimal) 將整型值轉(zhuǎn)換為十六進(jìn)制數(shù)字字符串 
p (pointer) 將指針值轉(zhuǎn)換為十六進(jìn)制數(shù)字字符串 
s (string) 拷貝字符串、字符、或字符指針值到一個輸出字符串 
e (exponential) 將浮點值轉(zhuǎn)換為指數(shù)表示的字符串 
f (floating point) 將浮點值轉(zhuǎn)換為浮點表示的字符串 
g (general) 使用浮點或指數(shù)將浮點值轉(zhuǎn)換為最短的十進(jìn)制字符串 
n (number) 將浮點值轉(zhuǎn)換為帶千位分隔符的浮點值 
m (money) 將浮點值轉(zhuǎn)換為現(xiàn)金數(shù)量表示的字符串,轉(zhuǎn)換結(jié)果取決于地域設(shè)置,詳見Delphi幫助文件的Currency and date/time formatting variables主題 


領(lǐng)會以上內(nèi)容最好的辦法是你親自進(jìn)行字符串格式化試驗。為了簡便起見,我寫了FmtTest 程序,它能將整數(shù)和浮點數(shù)轉(zhuǎn)換為格式化字符串。從圖7.2可見,程序窗體分為左右兩部分,左邊對應(yīng)整型數(shù)字轉(zhuǎn)換,右邊對應(yīng)浮點數(shù)轉(zhuǎn)換。

各部分的第一個編輯框顯示需要格式化為字符串的數(shù)值。第一個編輯框下方有一個按鈕,用來執(zhí)行格式化操作并在消息框中顯示結(jié)果;緊接著第二個編輯框用于輸入格式化類型串。你也可以單擊ListBox 控件中的任一行,選擇預(yù)定義的格式化類型串,也可以自行輸入,每輸入一個新的格式化類型串,該類型串就會被添加到列表框中(注意,關(guān)閉程序就失去了添加的類型)。

圖 7.2: 程序 FmtTest 的浮點值輸出 

 

本例只簡單使用了不同的控制文本來產(chǎn)生輸出,下面列出了其中一個Show 按鈕事件代碼:

procedure TFormFmtTest.BtnIntClick(Sender: TObject);
begin
  ShowMessage (Format (EditFmtInt.Text,
    [StrToInt (EditInt.Text)]));
  // if the item is not there, add it
  if ListBoxInt.Items.IndexOf (EditFmtInt.Text) < 0 then
    ListBoxInt.Items.Add (EditFmtInt.Text);
end;
這段代碼主要用EditFmtInt 編輯框的文本和EditInt 控件的值進(jìn)行了格式化操作。如果格式化類型串沒有在列表框中列出,那么輸入的串會被添加到列表框中;如果用戶在列表框中進(jìn)行點擊,代碼會把點擊的串移到編輯框中:

procedure TFormFmtTest.ListBoxIntClick(Sender: TObject);
begin
  EditFmtInt.Text := ListBoxInt.Items [
    ListBoxInt.ItemIndex];
end;
結(jié)束語 
字符串是一種很常用的數(shù)據(jù)類型,盡管在很多情況下不理解字符串怎樣工作也能安全使用它們,不過通過本章,了解了字符串的內(nèi)部運(yùn)行機(jī)制之后,你就能更充分地利用字符串類型的強(qiáng)大功能。

Delphi用特殊的動態(tài)方式處理字符串內(nèi)存,正如動態(tài)數(shù)組一樣,這將在下一章進(jìn)行討論。
 

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99视频一区二区| 一区二区三国产精华液| 韩国中文字幕2020精品| 久久久一区二区三区捆绑**| 国产激情一区二区三区| 中文字幕亚洲欧美在线不卡| 在线观看日韩高清av| 肉色丝袜一区二区| 精品免费日韩av| av成人免费在线| 性做久久久久久免费观看| 精品国一区二区三区| 成人激情动漫在线观看| 亚洲国产精品人人做人人爽| 日韩欧美电影一区| 不卡一区二区三区四区| 亚洲第一会所有码转帖| 国产亚洲1区2区3区| 在线视频欧美精品| 九色综合狠狠综合久久| 亚洲欧洲一区二区三区| 制服丝袜亚洲网站| 成人综合在线视频| 亚洲电影一区二区| 久久精品在线观看| 色88888久久久久久影院按摩 | 国产精品污www在线观看| 91色婷婷久久久久合中文| 日韩在线a电影| 国产精品女主播在线观看| 8v天堂国产在线一区二区| 成人丝袜视频网| 三级一区在线视频先锋| 亚洲天堂福利av| 精品免费一区二区三区| 欧美日韩中文字幕精品| 国产大陆精品国产| 日日骚欧美日韩| 日韩毛片视频在线看| 精品国产乱码久久久久久久久 | 麻豆成人久久精品二区三区红| 国产亚洲欧美日韩在线一区| 69久久夜色精品国产69蝌蚪网| 成人免费精品视频| 国产一区二区三区高清播放| 亚洲成人在线观看视频| 国产精品久久久久毛片软件| xnxx国产精品| 欧美一级高清大全免费观看| 91在线观看美女| 岛国av在线一区| 国产一区二三区好的| 蜜臀av亚洲一区中文字幕| 一区二区三区在线看| 国产精品欧美久久久久无广告 | 人禽交欧美网站| 亚洲一区二区视频在线观看| 中文字幕一区二区三区不卡| 国产欧美日韩视频在线观看| 日韩精品一区二区三区视频播放 | 综合色天天鬼久久鬼色| 国产清纯在线一区二区www| 欧美大片在线观看一区| 制服丝袜成人动漫| 欧美日本免费一区二区三区| 在线观看不卡一区| 欧美综合一区二区| 色先锋资源久久综合| 色欲综合视频天天天| 色综合天天综合色综合av| 成人激情图片网| 99精品久久99久久久久| 91免费国产视频网站| 91丨九色丨黑人外教| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 国产精品一区二区三区四区 | 日韩av一区二区在线影视| 亚洲成av人综合在线观看| 亚洲成人动漫av| 首页国产欧美日韩丝袜| 日韩国产欧美在线播放| 久久精品噜噜噜成人av农村| 日本aⅴ亚洲精品中文乱码| 老司机精品视频在线| 国产一区二区三区| 国产精品1024| 91视视频在线直接观看在线看网页在线看| 91色porny在线视频| 在线观看欧美日本| 日韩一区二区三区免费观看| 精品福利二区三区| 国产欧美精品国产国产专区 | 国产成人精品亚洲777人妖 | 日韩精品一区二区三区中文不卡| 日韩精品一区二区三区在线观看 | 精品久久一二三区| 久久综合狠狠综合| 亚洲色图另类专区| 亚洲成a人片在线观看中文| 美日韩一区二区三区| 国产精品综合视频| 91小视频在线观看| 911国产精品| 欧美国产日韩一二三区| 一区二区三区四区蜜桃| 另类人妖一区二区av| 成人污污视频在线观看| 色老头久久综合| 精品对白一区国产伦| 亚洲乱码国产乱码精品精的特点| 天天综合天天做天天综合| 国产精品一区二区三区99| 一本色道a无线码一区v| 日韩视频一区二区三区| 国产精品嫩草99a| 三级成人在线视频| 99久久er热在这里只有精品15| 欧美日韩国产综合草草| 国产精品久久久久久久久果冻传媒| 亚洲香肠在线观看| 国产不卡一区视频| 欧美久久久久久久久| 国产精品无遮挡| 日韩国产高清在线| 一本在线高清不卡dvd| 26uuu国产日韩综合| 午夜视黄欧洲亚洲| 91麻豆国产香蕉久久精品| 日韩免费视频一区| 夜夜嗨av一区二区三区网页| 国产美女在线精品| 日韩亚洲欧美综合| 亚洲午夜免费福利视频| 不卡一区中文字幕| 久久欧美一区二区| 热久久免费视频| 欧美日韩另类国产亚洲欧美一级| 国产精品伦理在线| 国产精品一区一区| 日韩精品在线看片z| 亚洲成人在线免费| 在线观看日韩毛片| 亚洲日本在线天堂| 成人免费视频caoporn| 精品精品欲导航| 免费视频一区二区| 制服丝袜国产精品| 午夜天堂影视香蕉久久| 欧美综合一区二区三区| 亚洲美腿欧美偷拍| 91视频免费看| 日韩美女精品在线| 99久久er热在这里只有精品66| 国产婷婷色一区二区三区在线| 精品一区二区精品| 日韩免费视频一区| 久久97超碰国产精品超碰| 5858s免费视频成人| 天天色图综合网| 欧美电影在线免费观看| 天堂va蜜桃一区二区三区漫画版| 91黄色免费观看| 亚洲一区在线观看免费| 欧美无砖砖区免费| 亚洲成人免费视| 欧美一级一区二区| 精品一区二区三区不卡| 久久夜色精品国产噜噜av| 国产精品一区二区在线观看网站| 久久久噜噜噜久久人人看| 激情综合网最新| 国产亚洲综合av| 99久久久精品| 一区二区三区在线免费视频| 欧美丝袜丝nylons| 日本女人一区二区三区| 精品国产a毛片| 国产成a人无v码亚洲福利| 日韩美女久久久| 精品视频一区二区不卡| 青青草国产成人99久久| 精品国产sm最大网站免费看| 成人永久aaa| 亚洲制服丝袜av| 日韩一区二区三区免费看| 国产精品18久久久久久久久| 国产精品传媒入口麻豆| 欧美亚洲国产一区二区三区| 日韩和欧美的一区| 欧美精品一区男女天堂| 不卡的电影网站| 亚洲国产精品一区二区久久恐怖片| 欧美一级在线视频| 成人免费av在线| 天堂精品中文字幕在线| 欧美国产亚洲另类动漫| 欧美日韩国产影片| 国内精品伊人久久久久av影院 | 26uuu精品一区二区在线观看| 成人激情文学综合网|