6

我在 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 中的有效八进制数?

4

7 回答 7

9

你会想在 Tcl wiki 阅读Tcl 和 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
}
于 2010-01-21T18:31:31.317 回答
4

这是最干净的解决方案:

% 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

scan这可能是你关心的。"09"(甚至作为字符串)转换为十进制数9

注意:
1. 如果该值不能转换为十进制值,则scan返回一个空字符串({})。
2. 如果给scan命令提供了变量名(number如上例中的变量),则返回值指示状态0:解析十进制失败,和1:成功。

expr:此处用于演示expr将值解释为数字,并解决原始问题。它评估一个表达式(例如expr {2*3}返回6)。

于 2014-02-09T23:31:07.283 回答
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
于 2010-12-17T16:25:46.367 回答
2

我的所有这些 Tcl/Tk 8.1 版程序都已损坏,因为 Tcl/Tk 8.5.10 没有正确处理字符串/数字转换。

在这里,shell 进入 Tcl,然后输入:

 %  expr {01}
 1

(等等..)

 %  expr {06}
 6

 %  expr {07}    
 7

然后我们到8点...

 %  expr {08}
 missing operator at "_@_"

看起来像无效的八进制数

但它变得更糟。仍然在 Tcl shell 中,试试这个:

在我的 Tcl8.1 外壳中:

 % 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 shell。我已经确认该版本至少可以正确处理数字 08 的格式语句。Tcl 8.5.10 shell 根本没有。

于 2011-10-15T07:41:15.347 回答
1

这个链接应该可以帮助你

有效的八进制数只能包含数字 0-7,并且必须以 0 开头

于 2010-01-21T16:30:27.537 回答
1

就个人而言,我一直使用:

set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}]

消毒$troublesome_numbers.

于 2010-01-21T16:45:48.243 回答
-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
于 2015-06-16T17:06:11.120 回答