Delphi在case語句中使用字符串
在case語句中使用字符串
(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
在 case 語句中使用字符串 --- by 熊恆(beta)
我今天要介紹的是一個比較另類的方法。大家都知道,case 語句只能對順序類型
(ordinal type)管用,那麼我們先看一下順序類型到底有那些呢:1)整型;2)字
符型;3)枚舉型。
於是也就演化出三種在 case 語句裏面使用字符串的方法(耐心看下去哦,最後一
種方法纔是今天的重點:-p):
假如我們的具體應用如下(理想的,但是錯誤的寫法):
str := 'Chongqing';
case str of // 編譯器將在這一行制止你 :-(
'Beijing': ShowMessage('First');
'Tianjing': ShowMessage('Second');
'Shanghai': ShowMessage('Third');
'Chongqing': ShowMessage('Forth');
else ShowMessage('Other');
end;
(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法一:字符串轉爲整型
這應該是比較通行的方法了,主要是利用 TStringList。先把備選的字符串挨個
Add 進去,然後調用其 IndexOf 方法。該方法返回一個整數,表示待找字符串出
現在列表中的位置:
//var strList: TStringList;
strList := TStringList.Create;
strList.Add('Beijing');
strList.Add('Tianjing');
strList.Add('Shanghai');
strList.Add('Chongqing');
str := 'Chongqing';
case strList.IndexOf(str) of
0: ShowMessage('First');
1: ShowMessage('Second');
2: ShowMessage('Third');
3: ShowMessage('Forth');
else ShowMessage('Other');
end;
strList.Free;
可以看到,這是比較麻煩的方法了,不過你可得記住這個方法,因爲後面的討論
將會講到,這是最通用的方法。
另:當然,把字符串轉化爲整型後用於 case 不只這一種方法。另一種是通過把
備選項全部轉化爲等長度後合併爲一個字符串,然後用 Pos 函數返回某字符串的
位置。在此不再累述,請查閱《程序員》雜誌(具體哪一期不記得了:-()。
(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法二:字符串轉爲字符型
這應該是最簡單的一種方法,不過侷限性比較大。如果你的備選項的第 N 個字
符(N 應爲常數)都互不相同,那麼你賺到了。這樣,就可以通過取出這個字符,
來唯一標識你的字符串:
str := 'Chongqing';
case str[1] of // 第一個字符都不同,所以取出第一個進行比較
'B': ShowMessage('First');
'T': ShowMessage('Second');
'S': ShowMessage('Third');
'C': ShowMessage('Forth');
else ShowMessage('Other');
end;
不過如果你的備選項沒有這樣的特性,那麼你就無緣使用這種方法了。
(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法三:字符串轉爲枚舉型
這種方法主要用到 RTTI 的特性。該方法的主要思路是,先把所有的備選項聲名
爲一個枚舉類型的值,那麼我們只要把要找的字符串也轉換爲枚舉型,那麼就可以
用 case 語句了。那麼通過什麼辦法把一個字符串轉化爲枚舉型呢?往下看:
// uses TypInfo; // 記得引用這個單元
// type TMyStrSel = (Beijing, Tianjing, Shanghai, Chongqing);
// 注意,上面這個定義不能放在某個函數內部哦,那樣的話,它就沒有運行類信息了
// var strSel: TMyStrSel;
str := 'Chongqing';
strSel := TMyStrSel(GetEnumValue(TypeInfo(TMyStrSel), str));
case strSel of
Beijing: ShowMessage('First');
Tianjing: ShowMessage('Second');
Shanghai: ShowMessage('Third');
Chongqing: ShowMessage('Forth');
else ShowMessage('Other');
end;
稍做解釋:GetEnumValue 函數返回一個字符串對應的枚舉型的值在某枚舉類型
中的位置(要知道枚舉類型是有順序的,要不怎麼叫順序類型呢:-)),然後通過
一個強制類型轉換將這個值轉化爲枚舉型。於是就實現了把字符串轉化爲枚舉型的
操作。
可以看到,在 case 語句這一段,我們的使用和理想中的使用方法幾乎是一樣的!
畢竟枚舉類型可以做到見名知意嘛。的確比用前兩種方法看起來直觀得多。
當然,這並不是萬能的方法,如果你的備選項有一個不符合 Delphi 的變量名命
名法則(如'AK-47'或中文等),則不能將其聲明爲一個枚舉型,於是就不能使用這
個方法。如果是這樣你就只能使用前兩種方法了。極端的情況下,至少你還有第一
種方法可以使用 :-) 但在不少的場合,這種方法還是適用的。
Case 語句中使用字符串
作者:
function CaseString (const s: string;
const x: array of string): Integer;
var i: Integer;
begin
Result:= -1; // Default return parameter
for i:= Low (x) to High (x) do begin
if s = x[i] then begin Result:= i; Exit; end;
end;
end;
search:= 'delphi3000';
case CaseString (search, ['delphi3000',
'delphipages',
'Torry's']) of
0: s:= 'Excellent!';
1: s:= 'Good source';
2: s:= 'Not bad!';
end;
/////////////////////////////////
const MatchingStrings = '*First*Second*Third*';
var sString: string;
...
// sString has the data you want to test
case pos('*'+sString+'*',MatchingStrings) of
1: // This is the match for 'First'
7: // This is the match for 'Second'
14: // This is the match for 'Third'
else // In this case there were no matches
end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
grp1: TGroupBox;
rb1: TRadioButton;
rb2: TRadioButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type TASK=(blue,green,black,white,maroon);
var
Form1: TForm1;
const
Taskzhaowang:TASK=blue;
Taskneizheng:TASK=green;
implementation
{$R *.dfm}
procedure asdf(t:task) ;
begin
case t of
blue:
ShowMessage('ZhaoWang:'+inttostr(Ord(t)));
green:
ShowMessage('NeiZhneg:'+inttostr(Ord(t)));
end;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
if(rb1.Checked) then asdf(Taskzhaowang);
if(rb2.Checked) then asdf(Taskneizheng);
end;
end.