2010-01-21 23 views
6

我在Tcl中使用前導零的數字時遇到了問題。我正在解析一些可以有前導零的數字,比如「0012」,它應該被解釋爲整數「12」。在Tcl中處理前導零的數字

$ 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中會構成一個有效的八進制數?

回答

7

您需要在Tcl wiki上閱讀Tcl and 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 
} 
+1

多行,是的,但「掃描」建議是我見過的最簡潔最容易理解的。 「set b [scan b%d]」符合我的需求。 forceInteger proc的其餘部分專門用於防禦性輸入驗證。 – 2010-01-21 18:49:12

1

This link應該幫助你

有效的八進制數字只能包含數字0-7,必須與0

+0

該鏈接建議編寫一個多行處理程序去掉零。我曾希望可能會更簡單一些。 – 2010-01-21 17:27:31

+0

更正八進制數字。傻我。當然「8」不是有效的八進制數字。內部關閉一個錯誤... – 2010-01-21 17:28:44

1

我個人一直使用啓動:

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

消毒$troublesome_number小號。

+0

此regsub方法是正確的,但非常類似於鏈接Mick Sharpe打開的鏈接之一。 – 2010-01-21 17:26:44

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 
2

我有所有這些的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 "[email protected]_" 

看起來像無效的八進制數

但是我情況變得更糟。仍然在Tcl的外殼,試試這個:

在我Tcl8.1殼:

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

但在我的新的和改進TCL8.5殼,我得到一個錯誤:

% 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 shell。我已確認該版本至少能正確處理編號爲08的格式 。 Tcl 8.5.10 shell根本就沒有。

+0

您應該使用[掃描「08」%d]而不是[格式「%.0f」「08」]。掃描將字符串「08」轉換爲數字(8)。格式將數字「08」轉換爲字符串,但在tcl中「08」是無效數字,因此在這種情況下不使用格式 – Hazem 2015-08-04 14:08:21

2

這就是最乾淨的解決方案:

% 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

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

EXPR:這裏用來證明expr解釋值作爲一個數字,解決了原來的問題。它評估一個表達式(例如expr {2*3}返回6)。

+0

如果您使用的數字非常大(即不是日期或時間),則使用以下語法:'' '掃描$ 9%11d 9''' – nikc 2014-02-09 23:58:25

-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