Tcl脚本语言教程 - 图文

更新时间:2023-12-08 01:17:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Tcl教程

TCL语法

■脚本、命令和单词符号…………………………………………………………………………..2

■置换(substitution) ……………………………………………………………………………..2 ■注释……………………………………………………………………………………………………..5

变量

■简单变量……………………………………………………………………………………………….5

■数组……………………………………………………………………………………………………..6 ■相关命令……………………………………………………………………………………………….6

表达式

■操作数………………………………………………………………………………………………...7

■运算符和优先级…………………………………………………….………………………………7 ■数学函数………………………………………………………………………………………………8

List

■list命令……………………………………………………………………………………………….10 ■concat命令…………………………………………………………………………………………10 ■lindex命令………………………………………………………………………………………….11 ■llength命令………………………………………………………………………………….…….11 ■linsert命令………………………………………………………………………………..……….11

■lreplace命令……………………………………………………………………………………….11■lrange 命令…………………………………………………………………………………………11 ■lappend命令………………………………………………………………….……………………12 ■lsearch 命令………………………………………………………………………...……………12 ■lsort命令…………………………………………………………………………….………..……13 ■split命令……………………………………………………………………………………….……13 ■join命令………………………………………………………………………………….….………13

控制流

■if命令……………………………………………………….……………………………….………13

■循环命令:while 、for、 foreach……………………………………………….………14 ■eval命令…………………………………………………………………………………….………15 ■source命令………………………………………………………………………………….….…16

过程(procedure)

■过程定义和返回值…………………………………………………………………………………16

■局部变量和全局变量………………………………………………………………………….….17

■缺省参数和可变个数参数………………………………………………………………….……17 ■引用:upvar…………………………………………………………………………..………..…18

字符串操作

■format命令……………………………………………………………………………………….…19 ■scan命令…………………………………………………………………………….…………….…20

1

■regexp命令 ■regsub命令 ■string命令 文件访问

■文件名

■基本文件输入输出命令

■随机文件访问 ■当前工作目录

■文件操作和获取文件信息

错误和异常

■错误

■从TCL脚本中产生错误 ■使用catch捕获错误 ■其他异常

深入TCL

■查询数组中的元素 ■info命令

TCL语法 > 脚本、命令和单词符号

一个TCL脚本可以包含一个或多个命令。命令之间必须用换行符或分号隔开,下面的两个脚本都是合法的: set a 1 set b 2 或

set a 1;set b 2

TCL的每一个命令包含一个或几个单词,第一个单词代表命令名,另外的单词则是这个命令的参数,单词之间必须用空格或TAB键隔开。

TCL解释器对一个命令的求值过程分为两部分:分析和执行。在分析阶段,TCL 解释器运用规则把命令分成一个个独立的单词,同时进行必要的置换(substitution); 在执行阶段,TCL 解释器会把第一个单词当作命令名,并查看这个命令是否有定义,如果有定义就激活这个命令对应的C/C++过程,并把所有的单词作为参数传递给该命令过程,让命令过程进行处理。

TCL语法 > 置换(substitution)

注:在下面的所有章节的例子中,'%'为TCL的命令提示符,输入命令回车后,TCL会在接着的一行输出命令执行结果。'//'后面是我自己加上的说明,不是例子的一部分。 TCL解释器在分析命令时,把所有的命令参数都当作字符串看待,例如:

2

%set x 10 //定义变量x,并把x的值赋为10 10

%set y x+100 //y的值是x+100,而不是我们期望的110 x+100

上例的第二个命令中,x被看作字符串x+100的一部分,如果我们想使用x的值'10' ,就必须告诉TCL解释器:我们在这里期望的是变量x的值,而非字符'x'。怎么告诉TCL解释器呢,这就要用到TCL语言中提供的置换功能。

TCL提供三种形式的置换:变量置换、命令置换和反斜杠置换。每种置换都会导致一个或多个单词本身被其他的值所代替。置换可以发生在包括命令名在内的每一个单词中,而且置换可以嵌套。

■变量置换(variable subtitution)

变量置换由一个$符号标记,变量置换会导致变量的值插入一个单词中。例如: %set y $x+100 //y的值是10+100,这里x被置换成它的值10 10+100

这时,y的值还不是我们想要的值110,而是10+100,因为TCL解释器把10+100看成是一个字符串而不是表达式,y要想得到值110,还必须用命令置换,使得TCL会把10+100看成一个表达式并求值。

■命令置换(command substitution)

命令置换是由[]括起来的TCL命令及其参数,命令置换会导致某一个命令的所有或部分单词被另一个命令的结果所代替。例如: %set y [expr $x+100] 110

y的值是110,这里当TCL解释器遇到字符'['时,它就会把随后的expr作为一个命令名,从而激活与expr对应的C/C++过程,并把'expr'和变量置换后得到的'10+110'传递给该命令过程进行处理。

如果在上例中我们去掉[],那么TCL会报错。因为在正常情况下,TCL解释器只把命令行中的第一个单词作为看作命令,其他的单词都作为普通字符串处理,看作是命令的参数。 注意,[]中必须是一个合法的TCL脚本,长度不限。[]中脚本的值为最后一个命令的返回值,例如:

%set y [expr $x+100;set b 300] //y的值为300,因为set b 300的返回值为300 300

3

有了命令置换,实际上就表示命令之间是可以嵌套的,即一个命令的结果可以作为别的命令的参数。

■反斜杠置换(backslash substitution)

TCL语言中的反斜杠置换类似于C语言中反斜杠的用法,主要用于在单词符号中插入诸如换行符、空格、[、$等被TCL解释器当作特殊符号对待的字符。例如: set msg multiple\\ space //msg的值为multiple space。

如果没有'\\'的话,TCL会报错,因为解释器会把这里最后两个单词之间的空格认为是分隔符,于是发现set命令有多于两个参数,从而报错。加入了'\\'后,空格不被当作分隔符,'multiple space'被认为是一个单词(word)。又例如: %set msg money\\ \\$3333\\ \\nArray\\ a\\[2] //这个命令的执行结果为:money $3333 Array a[2]

这里的$不再被当作变量置换符。 TCL支持以下的反斜杠置换:

Backslash Sequence Replaced By \\a Audible alert (0x7) \\b Backspace (0x8) \\f Form feed (0xc) \\n Newline (0xa) \\r Carriage return (0xd) \\t Tab (0x9)

\\v Vertical tab (0xb)

\\ddd Octal value given by ddd (one, two, or three d's) \\xhh Hex value given by hh (any number of h's)

\\ newline space A single space character. 例如:

%set a \\x48 //对应 \\xhh

H //十六进制的48正好是72,对应H % set a \\110 //对应 \\ddd

H //八进制的110正好是72,对应H

%set a [expr \\ // 对应\\newline space,一个命令可以用\\newline转到下一行继续 2+3] 5

4

■双引号和花括号

除了使用反斜杠外,TCL提供另外两种方法来使得解释器把分隔符和置换符等特殊字符当作普通字符,而不作特殊处理,这就要使用双引号和花括号({})。

TCL解释器对双引号中的各种分隔符将不作处理,但是对换行符 及$和[]两种置换符会照常处理。例如: %set x 100 100

%set y \ 100 ddd

而在花括号中,所有特殊字符都将成为普通字符,失去其特殊意义,TCL解释器不会对其作特殊处理。

%set y {/n$x [expr 10+100]} /n$x [expr 10+100] TCL语言教程 > TCL语法 > 注释

TCL中的注释符是'#','#'和直到所在行结尾的所有字符都被TCL看作注释,TCL解释器对注释将不作任何处理。不过,要注意的是,'#'必须出现在TCL解释器期望命令的第一个字符出现的地方,才被当作注释。 例如:

%#This is a comment %set a 100 # Not a comment

wrong # args: should be \ %set b 101 ; # this is a comment 101

第二行中'#'就不被当作注释符,因为它出现在命令的中间,TCL解释器把它和后面的字符当作命令的参数处理,从而导致错误。而第四行的'#'就被作为注释,因为前一个命令已经用一个分号结束,TCL解释器期望下一个命令接着出现。现在在这个位置出现'#',随后的字符就被当作注释了。

变量 > 简单变量

一个TCL的简单变量包含两个部分:名字和值。名字和值都可以是任意字符串。例如一个名为 “1323 7&*: hdgg\的变量在TCL中都是合法的。不过为了更好的使用置换(substitution),变量名最好按C\\C++语言中标识符的命名规则命名。 TCL解释器在分析一个变量置换时,只

5

List > concat命令

语法:concat list ?list...?

这个命令把多个list合成一个list,每个list变成新list的一个元素。

List > lindex命令

语法:lindex list index

返回list的第index个(0-based)元素。例: % lindex {1 2 {3 4}} 2 3 4

List > llength命令

语法:llength list 返回list的元素个数。例 % llength {1 2 {3 4}} 3

List > linsert命令

语法:linsert list index value ?value...?

返回一个新串,新串是把所有的value参数值插入list的第index个(0-based)元素之前得到。例:

% linsert {1 2 {3 4}} 1 7 8 {9 10} 1 7 8 {9 10} 2 {3 4} List > lreplace命令

语法:lreplace list first last ?value value ...?

返回一个新串,新串是把list的第firs (0-based)t到第last 个(0-based)元素用所有的value参数替换得到的。如果没有value参数,就表示删除第first到第last个元素。例: % lreplace {1 7 8 {9 10} 2 {3 4}} 3 3 1 7 8 2 {3 4}

% lreplace {1 7 8 2 {3 4}} 4 4 4 5 6 1 7 8 2 4 5 6

11

List > lrange命令

语法:lrange list first last

返回list的第first (0-based)到第last (0-based)元素组成的串,如果last的值是end。就是从第first个直到串的最后。 例:

% lrange {1 7 8 2 4 5 6} 3 end 2 4 5 6 List > lappend命令

语法:lappend varname value ?value...?

把每个value的值作为一个元素附加到变量varname后面,并返回变量的新值,如果varname不存在,就生成这个变量。例: % lappend a 1 2 3 1 2 3 % set a 1 2 3 List > lsearch命令

语法:lsearch ?-exact? ?-glob? ?-regexp? list pattern

返回list中第一个匹配模式pattern的元素的索引,如果找不到匹配就返回-1。-exact、-glob、 -regexp是三种模式匹配的技术。-exact表示精确匹配;-glob的匹配方式和string match命令的匹配方式相同,将在后面第八节介绍string命令时介绍;-regexp表示正规表达式匹配,将在第八节介绍regexp命令时介绍。缺省时使用-glob匹配。例: % set a { how are you } how are you % lsearch $a y* 2

% lsearch $a y? -1

List > lsort命令

语法:lsort ?options? list

这个命令返回把list排序后的串。options可以是如下值: -ascii 按ASCII字符的顺序排序比较.这是缺省情况。 -dictionary 按字典排序,与-ascii不同的地方是:

1 2

(1)不考虑大小写

(2)如果元素中有数字的话,数字被当作整数来排序.

因此:bigBoy排在bigbang和bigboy之间, x10y 排在x9y和x11y之间. -integer 把list的元素转换成整数,按整数排序. -real 把list的元素转换成浮点数,按浮点数排序. -increasing 升序(按ASCII字符比较) -decreasing 降序(按ASCII字符比较)

-command command TCL自动利用command 命令把每两个元素一一比较,然后给出排序结果。

List > split命令

语法:split string ?splitChars?

把字符串string按分隔符splitChars分成一个个单词,返回由这些单词组成的串。如果splitChars

是一个空字符{},string被按字符分开。如果splitChars没有给出,以空格为分隔符。例: % split \ how are you

% split \ how are you

% split \ h o w { } a r e { } y o u List > join命令

语法:join list ?joinString?

join命令是命令的逆。这个命令把list的所有元素合并到一个字符串中,中间以joinString分开。缺省的joinString是空格。例: % join {h o w { } a r e { } y o u} {} how are you

% join {how are you} . how.are.you 控制流 > if命令

TCL中的控制流和C语言类似,包括if、while、for、foreach、switch、break、continue等命令。

语法: if test1 body1 ?elseif test2 body2 elseif.... ? ?else bodyn?

TCL先把test1当作一个表达式求值,如果值非0,则把body1当作一个脚本执行并返回所得

13

值,否则把test2当作一个表达式求值,如果值非0,则把body2当作一个脚本执行并返回所得值……。例如: if { $x>0 } { .....

}elseif{ $x==1 } { .....

}elseif { $x==2 } { .... }else{ ..... }

注意,上例中'{'一定要写在上一行,因为如果不这样,TCL 解释器会认为if命令在换行符处已结束,下一行会被当成新的命令,从而导致错误的结果。在下面的循环命令的书写中也要注意这个问题。书写中还要注意的一个问题是if 和{之间应该有一个空格,否则TCL解释器会把'if{'作为一个整体当作一个命令名,从而导致错误。

控制流 > 循环命令

循环命令包括while、for、foreach等。 ■while命令

语法为: while test body

参数test是一个表达式,body是一个脚本,如果表达式的值非0,就运行脚本,直到表达式为0才停止循环,此时while命令中断并返回一个空字符串。 例如:

假设变量 a 是一个链表,下面的脚本把a 的值复制到b: set b \

set i [expr [llength $a] -1] while { $i>=0}{ lappend b [lindex $a $i] incr i -1 } ■for命令

语法为: for init test reinit body

参数init是一个初始化脚本,第二个参数test是一个表达式,用来决定循环什么时候中断,第三个参数reinit是一个重新初始化的脚本,第四个参数body也是脚本,代表循环体。下例与上例作用相同:

1 4

set b \

for {set i [expr [llength $a] -1]} {$i>=0} {incr i -1} { lappend b [lindex $a $i] } ■foreach命令 这个命令有两种语法形式 1、 foreach varName list body

第一个参数varName是一个变量,第二个参数list 是一个表(有序集合),第三个参数body是循环体。每次取得链表的一个元素,都会执行循环体一次。 下例与上例作用相同: set b \ foreach i $a{

set b [linsert $b 0 $i] }

2、 foreach varlist1 list1 ?varlist2 list2 ...? Body

这种形式包含了第一种形式。第一个参数varlist1是一个循环变量列表,第二个参数是一个列表list1,varlist1中的变量会分别取list1中的值。body参数是循环体。 ?varlist2 list2 ...?表示可以有多个变量列表和列表对出现。例如: set x {}

foreach {i j} {a b c d e f} { lappend x $j $i }

这时总共有三次循环,x的值为\。 set x {}

foreach i {a b c} j {d e f g} { lappend x $i $j }

这时总共有四次循环,x的值为\。 set x {}

foreach i {a b c} {j k} {d e f g} { lappend x $i $j $k }

这时总共有三次循环,x的值为\。

15

本文来源:https://www.bwwdw.com/article/zb6t.html

Top