Handling leading zeros in Tcl

I'm having problems with Tcl using numbers with leading zeros. I am parsing some numbers that may have leading zeros, such as "0012", which should be interpreted as the integer "twelve".

$ 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) 

What is the best way to handle numbers that can have leading zeros in Tcl?

On the side of the note, what would be a real octal number in Tcl if “08” is not valid?

+6
integer octal parsing tcl
source share
7 answers

You will want to read Tcl and Octal Numbers on the Tcl wiki. The canonical way is to treat your input as a string and use the scan command to extract the numbers. This leads to this, yes multi-line, proc:

 proc forceInteger { x } { set count [scan $x %d%sn rest] if { $count <= 0 || ( $count == 2 && ![string is space $rest] ) } { return -code error "not an integer: \"$x\"" } return $n } 
+7
source share
 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" 

simpler:

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

I have all these Tcl / Tk version 8.1 programs that were corrupted because Tcl / Tk 8.5.10 does not handle string / number conversions correctly.

Here's the shell in Tcl and type:

  % expr {01} 1 

(etc.)

  % expr {06} 6 % expr {07} 7 

and then we get 8 ...

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

looks like an invalid octal number

But everything is getting worse. Still in the Tcl shell, try the following:

In my Tcl8.1 shell:

  % format "%.0f" {08} 8 

But in my new and improved Tcl8.5 shell, I get an error message:

  % format "%.0f" {08} expected floating-point number but got "08" (looks like invalid octal number) 

This is just plain stupid! I have all this code that works fine in Tcl7.6 and Tcl8.1, but which started to give strange random results in Tcl8.5. Only when the number 08 happened to receive or use! I spent hours trying to understand the problem. But it turns out that this is just a nasty bag of code that I use!

So, I am publishing this disclosure as a warning.
Version Tcl / Tk 8.5.10 does not handle number eight correctly. If you are expecting normal behavior from your format operators, this will not happen. Your code will fly together until it encounters a string evaluated to {08}, and the Tcl 8.5.10 interpreter will generate an error because it assumes that {08} is the octal number of a special case, regardless of all other small numbers that you used will work perfectly!

One possible solution to the problem mentioned above is to upgrade to the Tcl 8.1 shell. I confirmed that this version at least handles the format operators for the number 08 correctly. Tcl 8.5.10 shell just does not.

+2
source share

This is the cleanest solution:

 % expr [ scan "08" %d ] - 1 7 

Further

 % 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 

scanning . This is probably what you care about. Converts "09" (even as a string) to the decimal number 9 .

Note:
1. If this value cannot be converted to a decimal value, then scan will return an empty string ( {} ).
2. If the variable name is specified in the scan command (for example, the number variable in the above example), then the return value indicates the status, 0 : could not parse the decimal number and 1 : success.

expr . Used here to demonstrate that expr interprets a value as a number and addresses the original question. It evaluates the expression (for example, expr {2*3} returns 6 ).

+2
source share

This link should help you.

Real octal numbers can only contain digits 0-7 and begin with 0

+1
source share

Personally, I always used:

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

for disinfection of $troublesome_number s.

+1
source share
 #!/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 
-one
source share

All Articles