教材:陳濤.Tcl 程式設計初步 tcl/tk入門經典(2)
1.幾個有用的指令
append 将值追加到字元串尾
format 字元串格式
scan 字元串分解
binary 二進制字元串操作
string options 字元串操作和指令集
subst 字元替代(替代特殊字元)
regexp 正規表達式(用于字元串模式比對)
regsub 用正規表達式進行字元串模式比對和替換
2.append 變量1 $變量2 将變量2的值追加到變量1的未尾。
3.format
與C 語言中的 printf 和 sprintf 函數的格式功能類似。
format spec value1 value2 ...
spec為格式說明字元串,valuex不變元,每個變元最多有6個關鍵詞:位置說明符、标志、字段寬度、精度、長度和轉換符。
格式轉換符與C類似,格式标志符:"-"表示左對齊,"+"右對齊,“space”在數字前沒有前導符時,加一個空格,"0"用0補空白,前導o為八進制,x為十六進制。
位置說明符i$表示從第i個變元取數值,從1開始。
例:set res [format "%2\$s" 1 5 9] 取第二個變元的值5。
format "%o"20; 8進制輸出20,結果為24
format "%x" 20; 16進制輸出20,結果為14
format "%8x" 20; 16進制輸出20,寬8位,右對齊,結果為——————14,“—”表示空格
format "%08x" 20; 16進制輸出20,寬8位,右對齊,左補0,結果為00000014
format "%-8x" 20; 16進制輸出20,寬8位,左對齊
format "%#x" 20; 16進制輸出20,字首為0x,結果是0x14
format "%#8x" 20;16進制輸出20,字首為0x,結果是0x00000014
format %c%e%c 40 30000 41;結果是(3.000000e+04),40和41的ASCII碼為"("和")",%e是科學記數法
4.scan string format var? var? ....
與format相反,scan根據格式描述符來解析一個字元串并将對應值賦給後面的變量,傳回成功轉換的個數,如果沒有指定輸出變量則傳回成功解析的結果。string是待解析的字元串,第二個是控制解析方式的格式字元串
後面的參數用來存儲轉換出的值。
例 scan "16 units,24.2% margin" "%d units,%f" a b; 結果是2 ;同時a = 16,b = 24.2
該操作同時掃描string和格式,除了被忽略的空格和制表符及% 字元,格式必須和字元串中的字元一一對應,上個例子中,16對應了%d,units,對應units,
24.2對應%f,格式不比對的字元解析将失敗。
有時候空格、制表符不能被忽略,如格式為%c時,%c是将string中的相應字元轉換為整型。
例 scan "a%2" "%c%c%c" a b c;運作結果為3,表示成功轉換了3個結果;a b c的值分别是97 37 51。
5.scan的幾個常見用途
一是簡單地解析字元串,上一小節中第一例這樣的例子
二是将ASCII字元轉換成對應的整型數字,上小節第二例如是
三是将可能是0開頭的數字組成的字元串轉換為整型數字
例 proc forceDecimal {x} {
set count [scan $x {%lld %c} n c]
if {$count != 1} {
error "not an interger"
}
return $n
}
set val 0987
expr { [forceDecimal $val + 1]}
運作結果是988,如果沒有調用forceDecimal 函數,而是expr {$val + 1};則會報錯。%lld支援無限精度,可存儲任意大小的整數。
6.binary
對于數值來說,二進制(這裡說的二進制是資料在機器中的存儲方式,後面所說的八進制等隻是表現形式)可能比ASCII碼更省存儲空間,tcl提供了數字的ASCII碼和n進制碼的轉換:
binary format spec value1 ?value2 ...? 将數值類型轉換為ASCII
binary scan string spec var1 ?var2 ...? 與上相反
spec 為格式描述字元串
例 set b [binary format "s" 25664] ; 将整型數25664(在記憶體中占4位)轉換成字元串“25664”(在内中占5位),運作結果是"@d"。
25664的二進制表示是0110,0100,0100,0000,高8位是100,對應ASCII為"d",低8位是64,對應"@"
小寫的s是從低位開始排列,是以結果是"@d"。
binary scan "@d" "s" var; 執行後puts $var的結果是25664
這裡的格式字元前沒有加"%",下面列出二進制轉換的格式字元
類型 說明
a 包含 count 個字元的字元串。在 binary format 中以空字元作為補白
A 和 a 功能相同,隻不過使用空格符而不是空字元作為補白。
b 長度為 count 的二進制字元串,以 0 和 1 組成,按照從低到高的 bit 位順序排列
B 長度為 count 的二進制字元串,以 0 和 1 組成,按照從高到低的 bit 位順序排列
h 長度為 count 的十六進制字元串,按照從低到高的位元組順序組成
H 長度為 count 的十六進制字元串,按照從高到低的位元組順序組成
c 一個 8 位字元編碼。binary scan 中會從字元串中将字元轉換為對應整數
s 位元組順序為 little-endian 的 16 位整數。count 用于指定重複特性
S 位元組順序為 big-endian 的 16 位整數。count 用于指定重複特性
i 位元組順序為 little-endian 的 32 位整數。count 用于指定重複特性
I 位元組順序為 big-endian 的 32 位整數。count 用于指定重複特性
f 本機格式的單精度浮點數。count 用于指定重複特性
d 本機格式的雙精度浮點數。count 用于指定重複特性
x 使用 binary format 放置 count 個空位元組。使用 binary scan 跳過 count 個字
節
X 回退 count 個位元組
@ 跳到由 count 指定的絕對位置。如果 count 為*則跳到末尾
有些字元在終端居然顯示不出來,比如224對應的ASCII字元,通常顯示成個這"" !?
7.subst
{}中的$,\,[,]等符是不做替換的,但需要替換的時候也可以用subst實作
set a hello!
subst [{a = $a}] 運作結果是a = hello!
如果改成:subst {[puts {a = $a}]b = $a}; 結果就是a = $a b = hello!;了解是,解析器解析的時候,先将{a = $a}傳遞給了puts指令,puts指令執行完全後,再
将結果a = $a 和 後面的字元串b = $a 傳遞給subst,因為解析器不對結果進行第二次解析,是以a = $a這裡不進行替換。