Обработка чисел с ведущими нулями в Tcl
У меня проблемы с 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?
на боковой ноте, что будет представлять собой действительное восьмеричное число в Tcl, если" 08 " является недопустимым?
7 ответов
вы захотите прочитать Tcl и Восьмеричные числа в вики Tcl. Канонический способ-рассматривать ваш ввод как строку и использовать scan
команда для извлечения чисел. Что приводит к этому, да multiline, 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
}
у меня есть все эти программы Tcl / Tk версии 8.1, которые стали сломанными, потому что Tcl/Tk 8.5.10 не обрабатывает строки / числовые преобразования правильно.
здесь, оболочка в 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 неправильно обрабатывает число восемь. Если ты ...
ожидая разумного поведения от ваших операторов формата, это не будет.
Ваш код будет летать, пока не встретит строку со значением {08}, и
интерпретатор Tcl 8.5.10 создаст ошибку, потому что он будет предполагать
что {08} является специальным случаем восьмеричное число, независимо от того, что все
другие маленькие числа, которые вы использовали, будут работать просто отлично!
одно из возможных решений к проблеме, упомянутой выше, является понижение до Tcl 8.1 ракушка. Я подтвердил, что эта версия по крайней мере обрабатывает формат операторы для номера 08 правильно. Tcl 8.5.10 shell просто не делает.
set $clean_number [regsub {^0*(.+)} $troublesome_number {}] this doesnt work
set clean_number ""
set $troublesome_number 08
% set $clean_number [regsub {^0*(.+)} $troublesome_number {}]
wrong # args: should be "regsub ?switches? exp string subSpec varName"
более простое решение-это:
set x 08
regsub {^[0]} $x {} x
puts $x
=>8
это самое чистое решение:
% 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
: не удалось разобрать decimal и1
: успехов.
expr : используется, чтобы продемонстрировать, что expr
интерпретирует значение как число и обращается к исходному вопросу. Он оценивает выражение (например,expr {2*3}
возвращает 6
).
этой ссылке должно помочь вам
действительные восьмеричные числа могут содержать только цифры 0-7 и должны начинаться с 0
лично я всегда использовал:
set $clean_number [regsub {^0*(.+)} $troublesome_number {}]
санировать $troublesome_number
s.
#!/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 {} num
puts $num