parsing - Manejo de números con ceros a la izquierda en Tcl
integer octal (7)
Estoy teniendo problemas en Tcl usando números con ceros a la izquierda. Estoy analizando algunos números que pueden tener ceros a la izquierda, como "0012", que debe interpretarse como el entero "doce".
$ 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)
¿Cuál es la mejor manera de manejar números que pueden tener ceros a la izquierda en Tcl?
En una nota lateral, ¿qué constituiría un número octal válido en Tcl, si "08" es inválido?
Esta es la solución más limpia:
% expr [ scan "08" %d ] - 1
7
Además:
% 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
escaneo : esto es probablemente lo que te importa. Convierte el "09"
(incluso como una cadena) en un número decimal 9
.
Nota:
1. Si este valor no se puede convertir en un valor decimal,scan
devolverá una cadena vacía ({}
).
2. Si se proporciona un nombre de variable al comando descan
(como la variable denumber
en el ejemplo anterior), el valor de retorno indica el estado ,0
: no se pudo analizar el decimal, y1
: éxito.
expr : se usa aquí para demostrar que expr
interpreta el valor como un número y responde a la pregunta original. Evalúa una expresión (por ejemplo, expr {2*3}
devuelve 6
).
Personalmente siempre he usado:
set $clean_number [regsub {^0*(.+)} $troublesome_number {/1}]
para desinfectar $troublesome_number
s.
Tengo todos estos programas de la versión 8.1 de Tcl / Tk que se han roto porque Tcl / Tk 8.5.10 no está manejando las conversiones de cadena / numéricas correctamente.
Aquí, shell en Tcl, y escriba:
% expr {01}
1
(y así..)
% expr {06}
6
% expr {07}
7
y luego llegamos a 8 ...
% expr {08}
missing operator at "_@_"
parece un número octal inválido
Pero empeora. Aún en shell Tcl, intente esto:
En mi shell Tcl8.1:
% format "%.0f" {08}
8
Pero en mi nuevo y mejorado shell Tcl8.5, me sale un error:
% format "%.0f" {08}
expected floating-point number but got "08" (looks like invalid octal number)
Esto es simplemente tonto! Tengo todo este código que funciona bien en Tcl7.6 y Tcl8.1, pero que comenzó a dar resultados extraños y aleatorios en Tcl8.5. ¡Solo cuando el número 08 pasó a ser generado o usado! He pasado horas tratando de resolver el problema. ¡Pero resulta que es solo un desagradable saco de código el que estoy usando!
Entonces, estoy publicando esta diatriba como una advertencia.
La versión 8.5.10 de Tcl / Tk maneja incorrectamente el número ocho. Si espera un comportamiento sensato en sus declaraciones de formato, esto no sucederá . Su código volará, hasta que encuentre una cadena valorada en {08}, y el intérprete de Tcl 8.5.10 generará un error, ya que supondrá que {08} es un número octal de caso especial, independientemente del hecho de que todos los otros pequeños números que has usado habrán funcionado bien!
Una posible solución al problema mencionado anteriormente es rebajar de nuevo a una shell Tcl 8.1. Confirmé que esa versión al menos maneja las declaraciones de formato para el número 08 correctamente. Tcl 8.5.10 shell simplemente no lo hace.
Querrá leer Tcl y Octal Numbers en la wiki de Tcl. La forma canónica es tratar su entrada como una cadena y usar el comando de scan
para extraer los números. Eso lleva a esto, sí, multilínea, 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
}
Este enlace debería ayudarte
Los números octales válidos solo pueden contener los dígitos 0-7 y deben comenzar con 0
#!/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
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"
una solución más fácil es:
set x 08
regsub {^[0]} $x {/1} x
puts $x
=>8