TCL中的字符串解析命令SCAN
在TCL中scan命令提供的功能与ANSI C库中的 sscanf函数几乎完全一样。它从一个有格式的字符串开始,在格式字符申控制下解析这个字符串,取得与格式字符串中%转换符相对应的字段,把这些字段的值置于TCL变量中。例如,在执行下面这条命令以后,变量a的值为16,变量b的值为24.2。
scan "16 units, 24.2% margin”"% dunits, %f" a b
→2
scan获取的第一个参数是待解析的字符串,第二个参数是控制解析方式的格式字符串,其他的参数是用来存储转换出的值的变量。返回值2说明成功完成了两次转换。
scan操作同时扫描字符串和格式。除了被忽略的空格和制表符及%字符,格式必须与字符串中对应的字符匹配。除了少数几种情况,如%c,字符串中的空白都会被忽略。
例1、字符串的格式转换:将ASCII字符转换为它们对应的整型值,即使用%c转换符。
set char "x"
set value [scan $char %c]
→120
例2、数值类型转换:把一个可能由0开头的数字组成的字符串强制转换为十进制整数。通常情况下开头的0会让TCL把该数字字符串解析为八进制的数值以供计算使用。下面这个过程强制将一个数字字符串解析为十进制数。
proc forceDecimal {x} {
set count [scan $x {%11d %c} n c]
if {$count !=1} {
error "not aninteger: \"$x\""
}
return $n
}
set val 0987
expr {$val+1}
→cant use invalid octal number as operandof "+"
expr { [forceDecimal $val] +1}
→988
forceDecimal xyz
→not an integer:"xyz"
在这个forceDecimal实现中,使用了scan命令处理参数格式,可以把跟在数字字符后面的非数字字符识别出来。如果只是用%d作为格式参数,那么scan命令会把字符串123xyz中的123识别出来。转换符%11d中的11指定了用于存储整型数的空间的大小,它支持无限精度。如果没有这个11,转换后的值的存储空间会被限制为正在运行的系统中的机器字的大小。