Parsing 在Tcl中处理带前导零的数字

Parsing 在Tcl中处理带前导零的数字,parsing,integer,tcl,octal,Parsing,Integer,Tcl,Octal,我在Tcl中使用带前导零的数字时遇到问题。我正在分析一些可以有前导零的数字,比如“0012”,它应该被解释为整数“12” 处理Tcl中可能有前导零的数字的最佳方法是什么 另一方面,如果“08”是无效的八进制数,那么在Tcl中什么才是有效的八进制数呢?应该会对您有所帮助 有效的八进制数字只能包含数字0-7,并且必须以0开头。我个人一直使用: set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}] 要清理$Troublemy_nu

我在Tcl中使用带前导零的数字时遇到问题。我正在分析一些可以有前导零的数字,比如“0012”,它应该被解释为整数“12”

处理Tcl中可能有前导零的数字的最佳方法是什么

另一方面,如果“08”是无效的八进制数,那么在Tcl中什么才是有效的八进制数呢?

应该会对您有所帮助


有效的八进制数字只能包含数字0-7,并且必须以0开头。我个人一直使用:

set $clean_number [regsub {^0*(.+)} $troublesome_number {\1}]
要清理
$Troublemy_number
s.

您需要在Tcl wiki上阅读。规范的方法是将输入视为字符串,并使用命令提取数字。因此,是的,多行,过程:

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
}
proc forceInteger{x}{
设置计数[扫描$x%d%s n剩余]
如果{$count
更简单的解决方案是:

set x 08
regsub {^[0]} $x {\1} x
puts $x
=>8

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

在这里,将shell转换为Tcl,然后键入:

 %  expr {01}
 1
(等等)

然后我们到了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 如果您希望format语句的行为正常,则不会发生这种情况。 您的代码将继续运行,直到遇到一个值为{08}的字符串,然后 Tcl 8.5.10解释器将生成一个错误,因为它将假定 {08}是一个特殊的八进制数,不管 你用过的其他小数字会很好用的

上述问题的一个可能解决方案是降级回Tcl 8.1 我已经确认那个版本至少能处理格式
编号08的语句正确。Tcl 8.5.10 shell根本不正确。

这是最干净的解决方案:

% 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
变量),则返回值指示状态,
0
:解析十进制失败,
1
:成功


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

此regsub方法是正确的,但与Mick Sharpe打开的链接中的一个解决方案非常相似。该链接建议编写一个多行过程来去除零。我曾希望有更简单的方法。八进制数字正确。我真傻。当然是“8”不是有效的八进制数字。内部关闭一个错误…多行,是的,但“扫描”建议是我见过的最简洁、最容易理解的。“设置b[扫描b%d]”满足我的需要。forceInteger过程的其余部分用于防御性输入验证。如果您使用的是非常大的数字,即不是日期或时间,请使用以下语法:
scan$nine%11d nine
您应该使用[scan“08”%d]而不是[format”%.0f“08”]。扫描将字符串“08”转换为数字(8).format将数字“08”转换为字符串,但“08”在tcl中是无效的数字,因此在这种情况下不要使用format。实际上,对于您的示例,您是幸运的,并且会收到一条错误消息。如果字符串为011,您将默默地得到错误的数字。
 % format "%.0f" {08}
 expected floating-point number but got "08" (looks like invalid octal number)
% 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
#!/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