如图,tcl read阶乘程序报错,can't read "result": no such variable,但是看起来好像没问题啊

5297人阅读
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:24017次
排名:千里之外
原创:21篇
(2)(13)(1)(4)(2)【图文】TCL学习文档_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
TCL学习文档
上传于||文档简介
&&T​C​L
大小:134.00KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢 赛狗下注改单软件_足球比赛评分:哪个医院治疗癫痫病好?日往月来添疾病
 赛狗下注改单软件_足球比赛评分:哪个医院治疗癫痫病好?日往月来添疾病
 我。”沐川竹迎着他们,扑了上去。龙剑臣跺跺脚,喊了两声,和朱重八等人,向着反方向突围了。刚刚从菜馆中追出来的管中殇、唐文、唐刚见到了,立即追了上去。这是机会啊?霍青又一把拽
关键词:赛狗下注改单软件_足球比赛评分
 赛狗下注改单软件_足球比赛评分:哪个医院治疗癫痫病好?日往月来添疾病
合作媒体推荐
看过本文的人还看过1101人阅读
编程技术(5)
TCL程序安装说明:tcl安装程序必须放在根目录下,比如D:\。
tcl开讲了,今天是第一期,掌声鼓励鼓励。
第一期讲些基础的东西。
认识脚本、命令、单词
脚本是由一条或多条命令组成的可运行文件,像training.tcl就是一个脚本。
命令由一个或多个单词组成,第一个单词是命令名,其它的是单词是命令的参数。如:set a 7
命令由换行符或分号隔开,单词通过空格或制表符隔开。
tcl处理一个命令分两步:解析和执行。
在解析步骤中,tcl运用各种规则(替换、引用等),将命令分解为单词,并执行替换。tcl不关心单词的内容。
在执行步骤中,各单词才有具体意义,tcl解析器调用具体的命令过程,将命令中的全部单词传递给该过程。
所谓替换就是把单词中的原始字符替换成另外一些值
tcl提供三种替换:变量替换、命令替换、反斜线替换
变量替换由$符引发,将tcl变量的值插入单词中。
命令替换由[ ]引发,将命令的执行结果传递给其它命令。
反斜线替换由\引起,用于向单词中插入像换行符这样的字符,以及像[、$这样的会被tcl解析器认为是有特殊含义的字符。
垂直制表符(Vertical Tab)
八进制值
十六进制值
h=0-9,A-F,a-f
所谓引用就是利用特殊办法阻止解析器对$和分号等字符进行特殊处理,保留其本意。
tcl提供两种引用:双引号引用和大括号引用
双引号引用由& &引发,双引号是定界符,不属于单词的一部分。双引号取消其中的单词和命令分隔符的特殊解释。也即空格、制表位、换行以及分号都当做普通字符处理,但替换能正常进行。
大括号引用由{ }引号,大括号也是定界符。大括号取消单词中所有特殊字符的特殊意义,所有字符原封不动。
proc test1 {} {
& &#命令通过换行或分号隔开
&set a1 24 ;set b1 15
&set ab [expr $a1*$b1]
&set abc [set abcd 555]
&puts &a1 is $a1 \nb1 is $b1&
&puts &a1*b1 is $ab& ;#计算乘法
&puts &abc 是 $abc& &;#可以有中文
&puts {a1*b1 is $ab} ;#输出结果不变
tcl第二讲,今天我们做练习,将上一讲的知识消化吸收加以巩固,其中会穿插讲一些规则,初次学习编程语言,一定要将规范都整清楚。
上一讲讲到了这么知识点:
脚本、命令、单词
命令的分隔、单词的分隔
方括号引用里面可以有多条命令,用分号或换行符隔开,传递最后一条命令的值。
\ &、\$、\&对特殊字符不做转义
\n:换行符
\t:制表位
反斜线-换行符-下一行开头的空白,会被替换为一个空格,在tcl解析前就会单独执行
变量替换、命令替换、以及反斜线替换在双引号中能正常进行。
如果想要在双引号括起来的单词中包含双引号,则应该使用反斜线替换。
proc test2 { } {
& &set x 4
& &set a1 24 ;set b1 15
& &set y [ expr $x * 5 ; expr $x+10]&
& &set msg eggs:\ \$2.18/dozen\ngasoline:\ \$2.49/gallon & &&
& &set hello moyu\tyotc
& &set wahaha \&a1*b1\ is\ $ab\&
& &set tianlong \
& & & babu &
& &set msk &a1 is $a1; the square of a1 is [expr $a1*$a1]&
& &set name a.out
& &set msr &couldnt open file \&$name\&&&
大括号最重要的应用之一就是延期处理,
proc test3 {value list} {&
set count 0
& foreach e1 $list {
& &if $e1==$value {
& &incr count
& &return $count
要把一大段文字注释掉,可以用如下的方法:
proc test4 {value} {
& & puts &&come on,lets go&
& & while &{$value &=0} {
& & & &puts && value = $value&
& & & &incr value -1
proc test5 {value} {
& & puts &&come on,lets go&
& & if 0 {
& & while &{$value &=0} {
& & & &puts && value = $value&
& & & &incr value -1
有关替换命令的思考
1、替换的两条规则:
(a)tcl解析一条命令时,只从左向右解析一次,进行一轮替换。每个字符只会被扫描一次。
(b)每一个字符只会发生一层替换,而不会对替换后的结果再进行一次扫描替换。
2、替换可以用被用得十分复杂,但是不建议这么用。两种办法可以应对复杂替换:
(a)用format、subst及list等命令协助处理复杂的替换情况。
(b)建立过程,将复杂的操作隔离开来。
这次讲tcl的变量。tcl的变量分两种:简单变量和关联数组。
proc test6 { } {
& &set a6 jiangnanbaguai
& &set a6 12.6
& &set a6 [expr $a6*4]
& &puts $a6
& &append a6 32
上面这个例子有点意思。先看前面三步:
(a) set命令后面有两个参数,a6和&jiangnanbaguai,由于a6事前没有创建,所以这步动作是先创建a6变量,然后将jiangnanbaguai赋值给a6。
(b) set命令后面只有一个参数,a6,这种情况下返回变量的当前值,这好理解。
(c) set命令后面有两个参数,a6和12.6,由于a6事先已经创建,所以这步是修改a6的值。
简单变量的故事我们讲完了,现在我们来讲内部数据存储。
怎么理解?我们知道tcl是基于字符串的语言,tcl中所有的值都有字符串表达形式,其中一部分有效率更高的内部表达形式。tcl会根据需要自动转换字符串和内部表达形式。比如上面的例子:
(d) &set a6 12.6中,tcl只存储变量的字符串表达形式,也即tcl把12.6认为是个字符串,而不认为是浮点数等其它的形式。
(e) &set a6 [expr $a6*4],在执行expr命令时,tcl会把字符串值解析为该值的内部浮点数表达形式。当set命令把expr的结果传递给a6时,只有内部浮点数表达形式存在。
(f) &puts $a6,将a6重新当做字符串对待,tcl在保留该值的内部表达形式的同时,产生该值的字符串表达形式。
(g) append a6 32,由于该命令修改了a6的字符串表达形式,tcl会更新该值的字符串表达形式的同时释放其内部浮点数表达形式。
别忘了还有另一类变量我们还没讲,下面我们来看看关联数组是怎么回事。
proc test7 { } {
&set week(monday) &700
&set week(tuesday) &600&
&set week(wednesday) &500&
&set week(thursday) &400&
&set week(friday) &300&
&set week(saturday) &200&
&set week(sunday) &100&
&set weektotal 0
&puts &lets see how much we earn:&
&foreach day {monday tuesday wednesday thursday friday saturday sunday} &{
& &puts &&the earning of $day is: &$week($day)&
& &incr weektotal [expr $week($day)*8]
& &#set weektotal [expr $weektotal+$week($day)*8]
& puts &&-----------------------------------\nthe earning of weektotal is: &$weektotal&
(a) 数组是元素的集合,数组元素的名称由两部分组成:数组名(元素名)。数组名和元素名可以是任意的字符串。
(b) 数组是无序的数据结构,tcl内部使用一张哈希表存储数组元素。所谓哈希表就是散列表。tcl列表是有序列的。
数组元素的高端用法
proc test8 {} {
& set capital(new\ jersey) &trenton
& set &&capital(south dakota)& &pierre
& set state &new mexico&
& set capital($state) &&santa fe&
& set matrix(1,1) 140
& set matrix(1,2) 230
& set matrix(1,3) 84
& set i 1 ; set j 2
& set cell &$matrix($i,$j)
& puts & &the &capital of&new jersey&is: $capital(new\ jersey)&&&
& puts & &the capital of south dakota is: &$capital(south\ dakota)&&&&
& puts & &the capital of&new mexico&&is: &$capital($state)&&&
& puts & &the value of&cell&&is: &${cell}km &&
(a) 数组的元素中不要使用空格(包括二维数组),空格会将数组名称分隔成两个单词。
(b) 要在元素中使用空格,可以使用反斜线替换的空格符,或者将整个变量都用双引号括起来。
(c) 另一种办法是在元素名称中使用替换,替换不会影响命令中的单词定界。
(d) 大括号可以用于简单变量的定界,但不能用于指定数组中的某个元素。
(怎么输出再研究,先注释掉)
今天我们来讲表达式。
表达式是个什么概念,表达式是将操作符和操作码联系起来,产生一个新的值。
比如 expr 4+2中4+2就是一个表达式;再比如 if {$a&0} {puts &&hello world&&}中$a&0就是一个表达式。
表达式的操作数可以是整数和实数,也可以是字符串,用例子来看吧。
proc test9 {} {
& & set a [expr 335+553] & ;#都是十进制数
& & set b [expr 2] &;#都是八进制数,以0开头
& & set c [expr 0x14f+0xdec] & ;#都是十六进制数,以0x开头
& & #set d [expr 0b;0b] & &;#都是二进制数,以0b开头
& & puts &&$ $ $c &&
这个例子先放在这,后面还要继续补充的。
tcl的操作符分为5类:算术操作符、关系操作符、逻辑操作符、按位操作符、选择操作符。更高优先级的操作符在表中的位置更靠上。
a的负值
如果a&=b,结果为1否则为0
对a作一元加
如果a&=b,结果为1否则为0
逻辑非,a为1则0,a为0则1
如果a==b,结果为1否则为0
如果a!=b,结果为1否则为0
指数:a的b次方
如果a等于b,结果为1否则为0
如果a不等于b,结果为1否则为0
a除以b,结果取整
列表包含:a在b中,结果为1
a除以b取余数
非列表包含:a不在b,结果为1
a和b按位与
a和b按位异或
a和b按位或
a算数右移b位
逻辑与:a、b全1则结果为1
如果a&b,结果为1否则为0
逻辑或:a、b至少一个为1则结果为1
如果a&b,结果为1否则为0
选择:如果a非0,则b,否则为c
proc test10 {} {
& &set a 5 ;set b 3
& &#set mi [expr $a**$b]
& &set shang [expr $a/$b]
& &set yu [expr $a%$b]
& &set cha [expr ($a&$b)?($b-$a):($a-$b)]
& &puts &$ $ $cha &
字符串的比较以字典的方式进行。
tcl第五讲:流程控制
今天我们来讲tcl比较重要的一块,从上一讲到这一讲跨越了一些内容:字符串操作、列表操作、字典,我们把这些内容放到后面去讲,先把tcl的框架搭起来。
tcl的流程控制命令有:if、switch、while、for、foreach、break、continue、eval、source。这些命令讲语法都不难,难的是如何灵活运用它们。下面我们一一来看。
if命令:if命令处理一个表达式,检测它的结果,然后根据这个结果选择执行脚本。
在下面的例子中if命令获取两个参数,第一个参数是表达式,第二个参数是一个tcl脚本。如果表达式为真,则处理tcl脚本,如果表达式为假,if不再进行更多的操作而直接返回。
proc test11 {} {
& & puts &please input a value of x:&
& & set x [gets stdin]
& & if {$x&0} {
& & & &set x [expr abs($x)]
& &puts &the abs of x is: $x&
在下面的例子中,if命令包含三个分支,每个分支语句包含一个tcl脚本,执行哪一个取决与y的值。如果一条if命令没有else子句,当所有的检测都不通过时,它就不会执行任何脚本,直接返回一个空字符串。
proc test12 {} {
& puts&&please input a value of y(range 1-2):&
& set &y [gets stdin]
& if {$y==1} {
& & &set y [expr exp($y)]
& & &puts &the exp of 1 is: $y&
& &} elseif {$y==2} {
& & &set y [expr exp($y)]
& & &puts &the exp of 2 is: $y&
& &} else {
& & &puts &the input is out of range&
在if命令中要注意书写规范,每一个左大括号都必须在它的前一个单词的同一行,因为换行符就是命令分隔符。下面的脚本就会被解析成两个命令:
switch命令:switch命令用一个值与很多模式比较,执行能匹配的那个模式梭对应的tcl脚本。
switch命令提供一下两种书写方式:
(a) 第一个参数是要检测的值,第二个参数是包含一个或多个元素对的列表。每一对元素第一部分是要与检测值进行比较的模式,第二部分是在模式匹配时所要执行的脚本。
switch $x {a {incr t1} b {incr t2} c {incr t3} }
(b)将模式和脚本作为独立的变量传入,而不是先组成一个列表。
switch $x &a {incr t1} b {incr t2} c {incr t3}&
第一种写法规范性强,可以把模式和tcl脚本写成一一对应的方式,第二种写法对模式参数调用替换更加方便。一般人们倾向第一种写法。
以第一种写法为例:
&proc test13 {} {
& puts&&please input a value of x(range 1-3):&
& set &x [gets stdin]
& switch $x & { 1 {set x [expr asin($x)]} 2 {set x [expr sqrt($x)]} 3 {set x [expr log10($x)] } }
也可以写成如下形式:
proc test13 {} {
& puts&&please input a value of x(range 1-3):&
& set &x [gets stdin]
& switch $x &{&
& & &1 & {set x [expr asin($x)]}&
& & &2 & {set x [expr sqrt($x)]}&
& & &3 & {set x [expr log10($x)]}&
说明:如果没有匹配的模式,tcl解析器不会执行任何脚本,switch返回一个空字符串。
switch命令支持三种模式匹配方式:
-exact 表示严格的字符串比较
-glob &表示sting match命令下的匹配
-regexp 表示正则表达式下的匹配
此处不一一展开,后面再讨论。
循环命令有三种:while、for、foreach
循环控制有两种:break、continue
循环命令用来把一段脚本执行一遍又一遍,不同之处在于进入循环前的设置,以及它们决定退出循环的方式。循环控制则可以提前退出部分或全部循环。下面一一来看:
while命令:两个参数,一个表达式加一个tcl脚本。先处理表达式,如果结果为非0就执行tcl脚本,不断循环,直到表达式为假,此时while命令终止,返回一个空字符串。
我们来看一个用while命令求乘阶的例子:
proc test14 {} {
& puts&&please input a value of x(x is int and x&0):&
& set &x [gets stdin]
& set x_label &the result of &${x}!:&
& set result 1
& while {$x&0} {
& & & set result [expr $result*$x]
& & & incr x -1
& puts &&$x_label $result &
for命令:四个参数,一个初始化脚本,一个决定终止循环的表达式,一个再初始化脚本(它在每执行完一次tcl脚本后,再次执行检测终止表达式之前执行)以及构成循环块的脚本。
for命令和while命令是等价的,for命令的优势是将所有的循环控制信息放在一起,易于查看。仍然是计算乘阶,我们来看看用for命令怎么做。
proc test15 {} {
& puts&&please input a value of x(x is int and x&0):&
& set &x [gets stdin]
& set x_label &the result of &${x}!:&
& for {set t $ set result 1} {$t&0} {incr t -1} {
& & & &set result [expr $result*$x]
foreach命令:最简单的foreach命令 三个参数,变量名、列表、构成循环体的tcl脚本。下面我们来看个例子:
proc test16 {} {
& & set t 0
& & foreach &i {-4 4 3 5 4 6 7 3 4 2} {
& & & & if {$i==4} {
& & & & & & &incr t&
& & & & &}
& & & return $t
foreach也可以做的很高端,比如除了简单变量名,foreach也支持变量名列表。 &
proc test16 {} {
& & foreach &{x y} {-4 4 3 5 4 6 7 3 4 } {
& & & puts &&&$x&&$y&&
下面这个更高端,用foreach命令并行处理多个列表。
proc test17 {} {
& & foreach &x {3 &4} {y z} {7 9 6 2 5 1} {
& & & &puts &&x:&$x&\ty:&$y&\tz:&$z&&
break:break命令让引起最内层循环的命令立即终止。
proc test18 {} {
& &set b { }
& &foreach i {-4 4 3 5 4 6 7 3 4} {
& & &if {$i==7} break
& & &set b [linsert $b 0 $i]
& & puts &$b
conrinue:continue命令只终止最内层循环的当前迭代步;循环继续执行它的下一迭代步。
proc test19 {} {
& &set b { }
& &foreach i {-4 4 3 5 4 6 7 3 4} {
& & &if {$i==4} continue
& & &set b [linsert $b 0 $i]
& & puts &$b
时间一下子过去了两天,这两天因为外部干扰不断,没法静下来搞学习,所以将TCL的学习荒废了。今天接着搞起来,将这两天的内容补起来。
另外我得说一件特沉重的事,前天电脑始终起不来,一怒之下装机了,放桌面的一些文档都被删了,这里面有辛辛苦苦准备了一周的知识梳理,还有TCL资料夹,套句大话就是“百年功业,毁于一旦”,要重新整一遍又得花不少功夫。所幸TCL学习笔记是放在云笔记上的,逃过一劫。这也给我提了个醒,重要资料要及时备份,另外还是要搭建一个统一的知识整理平台,以前自己学习的东西太零散了,效果没达到,既然旧的已去,那就在有道云笔记上面另起炉灶,重头再来。
真是道高一尺魔高一丈,我竟然把桌面的默认文件夹放在D盘,所有的文件都还在,thanks god,thanks earth。
过程由proc命令创建,虽然我们每天都会接触proc命令,但我们还是有必要来重新认识一下proc命令。
创建一个plus过程,输入两个参数,输出结果。
proc plus1 { a b } {
& & return [expr $a+$b]
proc命令由三个参数组成,第一个参数是过程的名称,前面的例子中我们用的是test1-19,上面的例子叫plus。第二个参数是由该过程所使用的参数组成的列表,第三个参数就是构成新的过程块的tcl脚本。&
关于第二个参数有这么几种用法:
1、输入的列表中有几个参数,在调用该过程时就得带几个参数,这是最基本的用法。比如上面的例子中,输入“plus 4 6”是可以的,输入“plus 4”就不行,少了一个参数。
2、对于上面的情况,我们可以设置部分参数或全部参数的默认值,因为参数列表实际上就是列表的列表,每一个子列表对应一个参数。不过默认参数必须放在参数列表的尾部。可以参考下面的plus2命令.
3、参数列表的第三个功能我们上面惯用的,在参数列表中指定一个空字符串,这种情况下过程不获取参数。
4、参数列表的高级用法是支持可变数量的参数。如果参数列表的最后一个元素是特殊名称args,那么调用过程时可以给出可变个数的参数。args放在列表的最后,且不能设置默认值,它的默认值是空字符串。
proc plus2 { value {increment 1} } {
& & & & return [expr $value+$increment]
proc findmax {args} {
& & & &set themax 0
& & & &foreach i $args {
& & & & & & &if {$i&$themax} {
& & & & & & & & set themax $i
& & & & &}
& puts &the max number of \{$args\} is:$themax&
全局变量和局部变量
过程中创建的变量(传给过程的参数)都是局部变量,这些变量仅能由这个过程访问,在过程返回后就被删除。
过程之外定义的变量叫全局变量,全局变量是长期存在的,仅在生命删除变量后才消失。
还有在命令空间里定义的变量,这些变量只有在特定的命令空间上下文环境中才能长期存在。
变量名可以相同,互不影响。
过程中可以使用globe命令调用全局变量,任何时候都行,一旦调用,一直有效,直到过程返回为止。
传引用调用
TCL只支持参数的传值调用。upvar命令提供访问当前过程的上下文范围之外的变量的通用机制,可以用于访问全局变量、命名空间变量以及其它活动中的过程内的局部变量。
proc test20 {name} {
& & &upvar $name a
& & &foreach el [lsort [array names a] ] {
& & &puts &$el=$a($el)&
set info(name) &jiangnan
set info(age) 26
set info(sex) man
创建新的控制结构
命名空间有点难度,我们慢点学,将知识要点都理解透了,以后写起程序来就轻松很多。
proc test21 {} {
&name current
&namespace children
&namespace children ::tcl
name current
&namespace children
::dom ::critcl ::platform ::activestate ::pkg ::tcl
namespace children ::tcl
(1) name current 返回当前命名空间的完全限定名称
(2) namespace children 返回指定命令空间的所有子命名空间的列表,如果没有指定namespace参数,就返回当前命名空间的子列表。
(3) 在命令空间内执行过程要用到namespace eval命令。这个命令获取命名空间的名称,在指定的命名空间中处理TCL脚本,返回脚本的结果。
proc test22 {} {
& &return &hello world!&
namespace eval ns {
& & proc &test22 {} {
& & &return &love life!&
(4) 要删除命名空间,而不是命名空间里的命令,可以用namespace delete命令,该命令获取命名空间的一个列表进行删除。
(5) 命名空间的变量可以由variable命令创建、赋值或访问。该变量对同一命名空间下的过程不做限定就能可见。在一个命名空间,如果访问一个没有由该命名空间创建的变量,会先在全局变量中进行查找,如果找到就使用该全局变量而不再另外创建命名空间变量。
namespace eval ns {} {
& & variable num 0
& & & &proc incr {} {
& & & & & variable num
& & & &return &num=[set num [expr $num+1]]&
& & &&&proc reset {} {
& & & & & variable num
& & & &return&&num=[set &num 0]&
(6) variable命令不能初始化数组的值,但它可以在命名空间中设置变量,允许过程访问它们。也就是说,数组要单独进行一步初始化操作。
namespace eval catalog {} {
& & &variable &object
& & &array set object {}
& & & &proc add {item} {
& & & & &variable object
& & & & &incr object($item)
& & & &proc getobject {} {
& & & & &variable object
& & & & &return [lsort [array names object] ]
& & & &proc countobject {item} {
& & & & &variable object
& & & & &return &$object($item)
(7) 操作限定名称。
限定名称由命名空间名称,加上::,再加上命令、变量或子命名空间变量名称组成。限定名称可以是绝对的,也可以是相对的,比如在全局命名空间可以使用相对 限定名称ns::incr调用incr过程,在其它命名空间使用该过程则要使用绝对限定名称::ns::incr。
可以使用namespace qualifiers命令来获取限定名称的空间命名部分,可以使用namespace tail命令获取限定名称的局部名称部分。
namespace qualifiers ::tcl::tm::jiangnan
namespace qualifiers tcl::tm::jiangnan
namespace qualifiers jiangnan
namespace tail&::tcl::tm::jiangnan
namespace tail tcl::tm::jiangnan
namespace tail jiangnan
set theNS ::tcl::tm
set theCommand &${theNS}::jiangnan &;#必须用花括号将theNS括取来,不然会认为theNS::jiangnan是一个变量。
(8) 命名空间的导出和导入命令
namespace export命令会修订和解析一个与命名空间相关的一个通配符模式列表,将命名空间中与其匹配的命令作为它的公共API导出。
namespace import命令可以获取一个通配符模式列表,以此确定要导入的命令。
namespace eval src {
& &proc a &{} {return &aipha&}
& &proc b &{} {return &beta&}
& &proc esc {} {return &exit&}
& &namespace export a b&
namespace eval dst {
& &namespace import ::src::*
& &proc c &{} {return &charlie&}
& &expr &{& [a] [b] [c] &}
&aipha beta charlie&
使用namespace import -force可以强制
命名空间复杂用法
先来讲讲历史。将历史是我们的专长,TCL语言的学习,涉及到很多使用习惯的问题,一不小心就会弄错。
TCL指定文件名来自于遵循unix的语法:
(1)文件x/y/z表示x目录在当前工作目录中,y目录在x目录下,z文件在y目录下。
(2)文件名/top指的是根目录下的top文件
(3)~表示用户的home文件夹,~user/box指用户user的home文件夹下的box文件,~/box指当前用户的home文件夹下的box文件。
&question:当前工作目录如何查看,当前工作目录和根目录的区别,home目录如何查看
&tcl提供两个命令管理当前工作目录,pwd和cd。
&pwd不获取参数,返回当前工作目录的完整路径。
&cd获取一个参数,将当前工作目录指向该参数值所指的目录,如果不带参数调用cd,则将当前工作目 录指向home目录。
接上文,windows系统使用反斜线做目标分隔符,而不是正斜线,这和unix系统是有区别的。为了处理文件命名的差异情况,可以使用file join和file split命名把文件名和目录名以跨平台的方式适当组合起来。
下面是我们自己的tcl脚本开头用到的命令:
set dir [file dirname [info script]]
if {[string equal $dir &.&]} {
& & set dir [pwd]
set log [file join $dir c85-1600.log]
file join命令将文件名和目录联系起来,无论各路径部分的原始样式如何,file join返回的都是unix样式的路径,以/符号作为分隔符。
(user) 15 % file join c:\ hello world tclsh.exe
c: hello/world/tclsh.exe
(user) 16 % file join c:\jiangnan hello world tclsh.exe
c:jiangnan/hello/world/tclsh.exe
(user) 17 % file join c:/ {program files} tcl tclsh.exe
c:/program files/tcl/tclsh.exe
正斜线不能显示,带空格的路径要用大括号括起来。
file split命令将一个文件名路径分割为它的各组成部分,例如:
(user) 19 % file split c:/program files/tcl/tclsh.exe
wrong # args: should be &file split name&
(user) 20 % file split c:/programfiles/tcl/tclsh.exe
c:/ programfiles tcl tclsh.exe
(user) 21 % file split x/y/z
(user) 22 %&
file nativename命令返回原生格式的文件名,比如将~符号展开为指定用户的home目录。
(user) 23 % file nativename ~/tcl/tclsh.exe
C:\user\tcl\tclsh.exe
file dirname移除文件名中的最后一个部分,表面看就是获得包括该文件的目录的名称,但是file dirname并不会检查是否真存在这么一个目录,这么一个文件。
(user) 29 % file dirname a/b/c
(user) 30 %&
file extension返回一个文件的扩展名,file rootname返回除扩展名以外的部分。
(user) 30 % file extension a/b/c.txt
(user) 31 % file rootname a/b/c.txt
(user) 32 %&
处理磁盘上的文件
TCL提供了很多命令对磁盘上的文件进行操作,如移动、重命名、复制以及删除等,它们直接调用操作系统函数来实现,与平台无关,效率极高。
file mkdir命令用来创建新的目录,在C:/user目录下还真的多了一个名为jianshan的空文件夹:
(user) 34 % file mkdir jianshan
(user) 38 % cd jianshan
(jianshan) 39 % pwd
C:/user/jianshan
(jianshan) 40 % cd
(user) 41 %&
file delete用来删除一个或多个文件,多个文件必须独立展开,不支持通配符匹配。
(user) 41 % file delete a.txt
(user) 42 % file delete a.txt b.txt c.txt
(user) 43 %&
file delete可以删除一个空目录,删除非空目录需要使用-force选项。
(user) 47 % file delete jianshan
(user) 48 % cd jianshan
couldn't change working directory to &jianshan&: no such file or directory
(user) 49 %&
file copy可以将源文件复制到一个不存在的目标文件,如果是复制到一个已经存在的目标文件,则需要使用-force选项。
(yotc) 52 % glob *.txt
(yotc) 53 % file copy a.txt b.txt
(yotc) 54 % glob *.txt
a.txt b.txt
(yotc) 55 %&
(yotc) 55 % pwd
C:/user/yotc
(yotc) 56 % file copy a.txt b.txt
error copying &a.txt& to &b.txt&: file already exists
(yotc) 57 % file copy -force a.txt b.txt
(yotc) 58 %&
还可以将一个文件复制到一个目标目录中,目标目录要用绝对路径。
(yotc) 60 % file &copy b.txt &~/moyu
file rename命令给一个文件或目录指定新的名称。
(yotc) 61 % glob *.txt
a.txt b.txt
(yotc) 62 % file rename b.txt c.txt
(yotc) 63 % glob *.txt
a.txt c.txt
(yotc) 64 %&
如果目标名称指向了另一个目录,file name命令就会把文件移动到新的位置
(yotc) 63 % glob *.txt
a.txt c.txt
(yotc) 64 % file rename a.txt ~/moyu
(yotc) 65 % glob *.txt
(yotc) 66 % cd
(user) 67 % cd moyu
(moyu) 68 % glob *.txt
a.txt b.txt ma.txt
TCL第十一讲
读写文件用open命令,该命令获取两个参数,文件名和访问模式。访问模式的几种类型如下:
指定文件必须存在。如果不指定访问模式,这是默认设置。
指定文件必须存在。
如果文件存在,将其清空;若文件不存在,则创建一个新的空文件。
如果文件存在,将其清空;若文件不存在,则创建一个新的空文件。
将初始访问位置设置为文件尾。如果文件不存在,则创建一个新的空文件。
将初始访问位置设置为文件尾。如果文件不存在,则创建一个新的空文件。
文件描述符
tcl提供了三个定义好的文件描述符,它们是stdin,stdout,stderr,分别指向标准输入,标准输入,以及运行TCL脚本的进程的错误信息通道。这些文件描述符由其它的命令调用,用于对打开的文件进行操作,如gets、puts、close等。一般来说,在打开文件时就把文件描述符存放在一个变量中,然后使用这个变量指向打开的文件。
TCL第十二讲
进程间通信
TCL第十三讲
错误与异常
大多数情况下,错误表示导致应用程序无法完全运行它正在处理的脚本的严重问题。
异常时导致脚本放弃运行的事件,这些事件包括break、continue和return命令,以及错误。TCL允许异常被脚本“捕获”,从而在出现异常时只绕开程序中的某部分工作。在捕获到异常后,脚本就可以从异常中恢复。
proc errorproc {x} {
&&if {$x & 0} {
&&& error &Error generated by error& &Info String for error& $x
catch errorproc
puts &after bad proc call: ErrorCode: $errorCode&&&&& ;#这里errorCode返回NONE
puts &ERRORINFO:\n$errorInfo\n&
set errorInfo &&;
catch {errorproc 0}
puts &after proc call with no error: ErrorCode: $errorCode&&& ;#这里errorCode返回NONE,没有错误提示信息
puts &ERRORINFO:\n$errorInfo\n&
catch {errorproc 2}
puts &after error generated in proc: ErrorCode: $errorCode&&& ;#这里errorCode返回2
puts &ERRORINFO:\n$errorInfo\n&
proc returnErr { x } {
& return -code error -errorinfo &Return Generates This& -errorcode &-999&
catch {returnErr 2}
puts &after proc that uses return to generate an error: ErrorCode: $errorCode&&& ;#这里errorCode返回999
puts &ERRORINFO:\n$errorInfo\n&&&&&&& ;#这里返回的错误信息第一行是设置值,但是后面还有其他错误信息
proc withError {x} {
& set x $a
catch {withError 2}
puts &after proc with an error: ErrorCode: $errorCode&
puts &ERRORINFO:\n$errorInfo\n&
catch {open &/no_such_directory/no_such_file& &r&}
puts &after an error call to a nonexistent file:&
puts &ErrorCode: $errorCode&
puts &ERRORINFO:\n$errorInfo\n&
运行脚本后的结果
% source error.tcl
after bad proc call: ErrorCode: NONE
ERRORINFO:
wrong # args: should be &errorproc x&
& & while executing
&errorproc&
after proc call with no error: ErrorCode: NONE
ERRORINFO:
after error generated in proc: ErrorCode: 2
ERRORINFO:
Info String for error
& & (procedure &errorproc& line 1)
& & invoked from within
&errorproc 2&
after proc that uses return to generate an error: ErrorCode: -999
ERRORINFO:
Return Generates This
& & invoked from within
&returnErr 2&
after proc with an error: ErrorCode: NONE
ERRORINFO:
can't read &a&: no such variable
& & while executing
&set x $a&
& & (procedure &withError& line 2)
& & invoked from within
&withError 2&
after an error call to a nonexistent file:
ErrorCode: POSIX ENOENT {no such file or directory}
ERRORINFO:
couldn't open &/no_such_directory/no_such_file&: no such file or directory
& & while executing
&open &/no_such_directory/no_such_file& &r&&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5150次
排名:千里之外

我要回帖

更多关于 阶乘是什么时候学的 的文章

 

随机推荐