Tcl语言参考(二)
二、Tcl变量数据类型
Tcl只支持一种数据类型:字符串(string)。所有的命令,命令的所有的参数,命令的结果,所有的变量都是字符串。请牢记这一点,所有的东西都是字符串。(然而字符串的实际解释是依赖于其所处上下文。它有三种形式:命令, 表达式和表)。Tcl变量根据其结构的复杂程度分为“简单变量”和“数组变量”两类。
(1)简单变量
一个Tcl的简单变量包含两个部分:名字和值,其中名字和值都可以是任意字符串。不过为了更好的使用变量置换功能,变量名最好按C\C++语言中标识符的命名规则命名。这是因为Tcl解释器在分析一个变量置换时,只把从$符号往后直到第一个不是字母、数字或下划线的字符之间的单词符号作为要被置换的变量的名字。例如:
set a 2
set a.1 5
set b $a.1
在最后一个命令行,我们希望把变量a.1的值付给b,但是Tcl解释器在分析时只把$符号之后直到第一个不是字母、数字或下划线的字符(这里是'.')之间的单词符号(这里是'a')当作要被置换的变量的名字,所以Tcl解释器把a置换成2,然后把字符串“2.1”付给变量b。这显然与我们的初衷不同。当然,如果变量名中有不是字母、数字或下划线的字符又要用变量置换,可以用花括号把变量名括起来。例如:
set b ${a.1}
(2)数组变量
数组是一些元素的集合。Tcl的数组和一般编程语言中的数组有很大的区别。在Tcl中,不能单独声明一个数组,数组只能和数组元素一起声明。数组中数组元素的名字包含两部分:数组名和数组中元素的名字,Tcl中数组元素的名字(下标〕可以为任何字符串。例如:
set day(monday) 1
set day(tuesday) 2
(3)重用结构及其操作
1、string结构及其操作
因为TCL把所有的输入都当作字符串看待,所以TCL提供了较强的字符串操作功能
【format】语法:
format formatstring vlue value...
format命令类似于ANSIC中的sprintf函数,它按formatstring提供的格式,把各个value的值组合到formatstring中形成一个新字符串,并返回。例如:
set msg [format "%s is %d years old" $name $age]
【scab】语法:
scan string formatsting varName varName ...
scan命令可以认为是format命令的逆,其功能类似于ANSI C中的sscanf函数。它按formatsting提供的格式分析string字符串,然后把结果存到变量varName中,注意除了空格和TAB键之外,string 和formatsting中的字符和'%'必须匹配。例如:
scan "some 26 34" "some %d %d" a b
【regexp】语法:
regexp [switchs] [--] exp string [matchVar]\ [subMatchVar subMatchVar...]
regexp命令用于判断正规表达式exp是否全部或部分匹配字符串string,匹配返回1,否则0。regexp可以设置一些开关(switchs〕,来控制匹配的具体方式,如:-nocase,-line等,其中-- 表示这后面再没有开关(switchs〕了,即使后面有以'-'开头的参数也被当作正规表达式的一部分。 如果regexp命令后面有参数matchVar和subMatchVar,则所有的参数被当作变量名,如果变量不存在,就会被生成。 regexp把匹配整个正规表达式的子字符串赋给第一个变量,匹配正规表达式的最左边的子表达式的子字符串赋给第二个变量,依次类推,例如:
regexp { ([0-9]+) *([a-z]+)} " there is 100 apples" total num word 1
puts " $total ,$num,$word"
显示结果为:100 apples ,100,apples
其他具体的正则表达式规则请参考Tcl语言手册
【regsub】语法:
regsub [switchs] exp string subSpec varname
regsub的第一个参数是一个整个表达式,第二个参数是一个输入字符串,这一点和regexp命令完全一样,也是当匹配时返回1,否则返回0。不过regsub用第三个参数的值来替换字符串string中和正规表达式匹配的部分,第四个参数被认为是一个变量,替换后的字符串存入这个变量中。例如:
regsub there "They live there lives " their x
puts $x
显示结果为:They live their lives
【sting】语法:
string subcmd arg [arg...]
string命令具有强大的操作字符串的功能,并通过其中的subcmd来区别具体将要执行的string操作。他们中的一些如下:
string length string
string range string first last
string index string charIndex
string tolower string [first] [last]
string replace string first last [newstring]
string equal [-nocase] [-length int] string1 string2
string match [-nocase] pattern string 如果pattern 匹配string,那么返回1,否则返回0.
string compare [-nocase] [-length int] string1 string2 如果有 -length 参数,那么只比较前 int 个字符
string first string1 string2 [startindex] 在string2 中从头查找与string1匹配的字符序列,如果找到,那么就返回匹配的第一
个字母所在的位置(0-based)。如果没有找到,那么返回-1。
string trim string [chars] 返回值为:从string字符串的首尾删除掉了字符集合chars中的字符后的字符串。如果没有给出chars,那
么将删除掉spaces、tabs、newlines、carriage returns这些字符.
2、list结构及其操作
list这个概念在TCL中是用来表示集合的。TCL中list是由一堆元素组成的有序集合,list可以嵌套定义,list每个元素可以是任意字符串,也可以是list。Tcl提供了很多基本命令对list进行操作:
【list】语法:
list [ value value...]
这个命令生成一个list,list的元素就是所有的value
【concat】语法:
concat list [list...]
这个命令把多个list合成一个list.
【llength】语法:
llength list
返回list的元素个数。
【lindex】语法:
lindex list index
返回list的第index个(0-based)元素。
【lrange】语法:
lrange list first last
返回list的第first (0-based)到第last (0-based)元素组成的串,如果last的值是end。就是从第first个直到串的最后。
【linsert】语法:
linsert list index value [value...?]
返回一个新串,新串是把所有的value参数值插入list的第index个(0-based)元素之前得到。
【lappend】语法:
lappend varname value [value...?]
把每个value的值作为一个元素附加到变量varname后面,并返回变量的新值,如果varname不存在,就生成这个变量。
【lreplace】语法:
lreplace list first last [value value ...]
返回一个新串,新串是把list的第firs (0-based)t到第last 个(0-based)元素用所有的value参数替换得到的。如果没有value参数,就表示删除第first到第last个元素。
【lsort】语法:
lsort [options?] list
这个命令返回把list排序后的串。options可以是如下值:
-ascii 按ASCII字符的顺序排序比较.这是缺省情况。
-dictionary 按字典排序,与-ascii不同的地方是:
(1)不考虑大小写
(2)如果元素中有数字的话,数字被当作整数来排序.
【lsearch】语法:
lsearch [-option] list pattern
返回list中第一个匹配模式pattern的元素的索引,如果找不到匹配就返回-1。option取-exact、-glob、 -regexp是三种模式匹配的技术,缺省时使用-glob匹配。
【join】语法:
join list [joinString]
这个命令把list的所有元素合并到一个字符串中,中间以joinString分开。缺省的joinString是空格。
【split】语法:
split string [splitChars]
把字符串string按分隔符splitChars分成一个个单词,返回由这些单词组成的串。如果splitChars 是一个空字符{},string被按字符分开。如果splitChars没有给出,以空格为分隔符。
3、file结构及其操作
TCL提供了丰富的文件操作的命令。通过这些命令你可以对文件名进行操作(查找匹配某一模式的文件)、以顺序或随机方式读写文件、检索系统保留的文件信息(如最后访问时间)。
3.1基本文件I/O
pwd和UNIX下的pwd命令完全一样, 没有参数,返回当前目录的完整路径。
cd 命令也和UNIX命令也一样,使用一个参数,可以把工作目录改变为参数提供的目录。
以下这个名为tgrep的过程,可以说明TCL文件I/O的基本特点:
proc tgrep { pattern filename} {
set f [open $filename r]
while { [gets $f line ] } {
if {[regexp $pattern $line]} {
puts stdout $line
}
}
close $f
}
open命令返回一个字符串用于表识打开的文件。当调用别的命令(如:gets,puts,close,〕对打开的文件进行操作时,就可以使用这个文件标识符。TCL有三个特定的文件标识: stdin,stdout和stderr ,分别对应标准输入、标准输出和错误通道,任何时候你都可以使用这三个文件标识。
3.2随即文件访问
默认文件输入输出方式是连续的:即每个gets或 read命令返回的是上次gets或 read访问位置后面的字节,每个puts命令写数据是接着上次puts写的位置接着写。TCL提供了seek,tell和eof等命令使用户可以非连续访问文件。每个打开的打开文件都有访问点,即下次读写开始的位置。文件打开时,访问点总是被设置为文件的开头或结尾,这取决于打开文件时使用的访问模式。每次读写后访问位置按访问的字节数后移相应的位数。
seek fileId offset [origin] 把fileId标识的文件的访问点设置为相对于origin偏移量为offset的位置。origin可以是start,current,
end,默认是start。
tell fileId 返回fileId标识的文件的当前访问位置。
eof fileId 如果到达fileId标识的文件的末尾返回1,否则返回0。
3.3文件操作和获取文件信息
【grob】语法:
glob [switches] pattern [pattern ...]
glob命令的模式采用string match命令的匹配规则,返回匹配这个(些)模式的所有文件的列表。如:
glob *.c *.h
glob */ 只返回当前目录的所有子目录。
【file】语法:
file subcmd arg [arg...]
file 通过众多的subcmd子操作提供强大的文件操作和访问能力。他们中的一些如下:
file exists name
file extension name
file mkdir dir [dir ...]
file copy [-force] [--] source target
file rename [-force] [--] source target
file delete [-force] [--] pathname [pathname ... ]