我在Tcl中遇到使用前导零的数字的问题。我正在解析一些可以有前导零的数字,例如“0012”,它应该被解释为整数“十二”。
$ tclsh
% set a 8
8
% set b 08
08
% expr $a - 1
7
% expr $b - 1
expected integer but got "08" (looks like invalid octal number)
处理Tcl中可能有前导零的数字的最佳方法是什么?
在旁注中,如果“08”是无效的,那么在Tcl中构成有效八进制数的是什么?
答案 0 :(得分:7)
您需要在Tcl wiki上阅读Tcl and Octal Numbers。规范方法是将输入视为字符串,并使用scan
命令提取数字。这导致了这个,是的多线,proc:
proc forceInteger { x } {
set count [scan $x %d%s n rest]
if { $count <= 0 || ( $count == 2 && ![string is space $rest] ) } {
return -code error "not an integer: \"$x\""
}
return $n
}
答案 1 :(得分:2)
set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}] this doesnt work
set clean_number ""
set $troublesome_number 08
% set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}]
wrong # args: should be "regsub ?switches? exp string subSpec varName"
更简单的解决方案是:
set x 08
regsub {^[0]} $x {\1} x
puts $x
=>8
答案 2 :(得分:2)
由于Tcl / Tk 8.5.10未正确处理字符串/数字转换,因此我已将所有这些Tcl / Tk版本8.1程序破坏。
这里,shell进入Tcl,然后输入:
% expr {01}
1
(等等......)
% expr {06}
6
% expr {07}
7
然后我们到8 ...
% expr {08}
missing operator at "_@_"
看起来像无效的八进制数
但它变得更糟。还是在Tcl shell中,试试这个:
在我的Tcl8.1 shell中:
% format "%.0f" {08}
8
但是在我新的和改进的Tcl8.5 shell中,我收到一个错误:
% format "%.0f" {08}
expected floating-point number but got "08" (looks like invalid octal number)
这只是傻瓜! 我有所有这些代码在Tcl7.6和Tcl8.1中正常工作,但它开始给出 奇怪,随机的结果在Tcl8.5。只有当08号码发生时 生成或使用!我花了好几个小时试图找出问题所在。 但事实证明,这只是我正在使用的令人讨厌的代码!
所以,我发布这个咆哮作为警告 Tcl / Tk版本8.5.10错误地处理了数字8。如果你是 期待您的格式语句中的理智行为,将不会发生。 你的代码将一直飞行,直到它遇到一个值为{08}的字符串,然后 Tcl 8.5.10解释器会产生错误,因为它会假设 {08}是一个特例八进制数,不管所有的情况如何 你用过的其他一些小数字都可以正常工作!
上述问题的一种可能解决方案是降级回Tcl 8.1 贝壳。我已经确认该版本至少可以处理格式 正确的数字08的陈述。 Tcl 8.5.10 shell根本就没有。
答案 3 :(得分:2)
这是最干净的解决方案:
% expr [ scan "08" %d ] - 1
7
此外:
% expr [ scan "09" %d ]
9
% expr [ scan 09 %d ]
9
% set nine 09
09
% expr [ scan $nine %d ]
9
% set success [ scan $nine %d number ]
1
% puts $number
9
扫描:这可能就是您关心的问题。将"09"
(即使是字符串)转换为十进制数9
。
注意:
1.如果此值无法转换为十进制值,则scan
将返回一个空字符串({}
)。
2.如果为scan
命令提供了变量名称(如上例中的number
变量),则返回值表示 status ,0
:无法解析小数,1
:成功。
expr :此处用于演示expr
将值解释为数字,并解决原始问题。它评估表达式(例如expr {2*3}
返回6
)。
答案 4 :(得分:1)
This link应该帮助你
有效的八进制数只能包含0-7位数,必须以0
开头答案 5 :(得分:1)
我个人经常使用:
set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}]
清理$troublesome_number
s。
答案 6 :(得分:-1)
#!/bin/tclsh
#Regsub TCL script to remove the leading zeros from number.
#Author : Shoeb Masood , Bagalore
puts "Enter the number"
set num [gets stdin]
regsub {^0*} $num {\1} num
puts $num