第一章:The Missing Code Library--6.合法化浮點數輸入

   咋一看,在一個shell腳本中合法化一個浮點值的過程看起來有些挫,但想一想看浮點數也不過就是一個用小數點分割開來的2個整數。聯繫第5個腳本validint.sh,你會發現浮點數合法化的測試短的讓人驚訝。 shell

代碼: 函數

#!/bin/sh
 
 # validfloat.sh -- 測試一個值是不是合法的浮點數
 # 注意,這個腳本並不能接受科學記數法形式的數字
 
 # 爲了測試是否合法,咱們須要在小數點位置分割數字。
 # 而後測試第一個部分,看看是否是一個合法的整數
 # 而後測試第二個,看看是否是>=0的整數。
 # 因此-30.5合法,-30.-8非法。
 
 source validint.sh
 
 validfloat()
 {
     fvalue="$1"
 
     if [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
         
         decimalPart="$(echo $fvalue | cut -d. -f1)"
         fractionalPart="$(echo $fvalue | cut -d. -f2)"
 
         if [ ! -z $decimalPart ]; then
             if ! validint "$decimalPart" "" ""; then
                 return 1
             fi
         fi
 
         if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
             echo "Invalid floating-point number: '-' not allowed \
 after decimal point" >&2
             return 1
         fi
 
         if [ "$fractionalPart" != "" ]; then
             if ! validint "$fractionalPart" "0" ""; then
                 return 1
             fi
         fi
 
         if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then
             if [ -z $fractionalPart ]; then
                 echo "Invalid floating-point format." >&2
             fi
         fi
 
     else
         if [ "$fvalue" = "-" ]; then
             echo "Invalid floating-point format." >&2
             return 1
         fi
 
         if ! validint "$fvalue" "" ""; then
             return 1
         fi
 
     fi
 
     return 0
 }
 
 if validfloat $1; then
     echo "$1 is a valid floating-point value"
 fi
運行腳本:
調用函數的時候,若是沒有報錯信息,返回碼是0,給定的數字就是一個合法的浮點數。經過增長下面幾行到腳本中來測試下:

if validfloat $1; then
    echo "$1 is a valid floating-point value"
fi
運行結果:

./validfloat.sh 1234.56
 1234.56 is a valid floating-point value
 ./validfloat.sh -1234.56
 -1234.56 is a valid floating-point value
 ./validfloat.sh -.75
 -.75 is a valid floating-point value
 ./validfloat.sh -11.-12
 Invalid floating-point number: '-' not allowed after decimal point
 ./validfloat.sh 1.0344e22
 錯誤的數字格式!只有數字,不能有逗號、空格等

在此提示下,在上面的腳本中用source引入validint.sh的時候,記得把validint中的最後幾行測試腳本註釋掉,不然會報錯的。source的用法可具體參考手冊頁。 測試

分析腳本:
   對上面的腳本的最好的擴展就是讓它支持科學記數法。就是最後一個測試的內容。這個並非
太難。你要測試下有沒有'e'或'E',而後將結果分割爲3個部分:
  小數點前的部分,只有一個數字;
  小數部分;
  指數部分。
   最後確保每一個部分都是整數。
   老七我本身想了一會,寫了一個,歡迎你們指正: spa

#測試科學記數法
 validfloat()
 {
     fvalue="$1"
     delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')"
 
     if [ ! -z $delimiter ]; then    #測試下是否有e或E
 
         if [ ${#delimiter} -ne 1 ]; then    #e或E不能有多個
             echo "only one e or E."
             return 1
         fi
         
         decimalPart="$(echo $fvalue | cut -d. -f1)"                #小數點前部分
         part="$(echo $fvalue | cut -d. -f2-)"                    #小數點後部分,注意f2後有一小橫,目的是輸出剩下的全部域
         fractionalPart="$(echo $part | cut "-d$delimiter" -f1)"    #小數點後,e前部分
         exponent="$(echo $part | cut "-d$delimiter" -f2)"        #e後部分
 
         if ! validint "$decimalPart" "-9" "9"; then                #測試小數點前的部分是否是一個數字,即0-9範圍內
             echo "scientific notation's decimal part abs must in [0-9]."
             return 1
         fi
 
         if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then    #測試小數部分第一個符號是否是負號
             echo "scientific notation's fractional portion cannot be negative."
             return 1
         fi
 
         if [ "$fractionalPart" = "" ]; then    #測試小數部分是否是爲空
             echo "scientific notation's fractional portion is empty."
             return 1
         else
             if ! validint "$fractionalPart" "" ""; then        #測試小數部分是否是整數
                 echo "scientific notation's fractional portion is not integer."
                 return 1
             fi
         fi
 
         if ! validint "$exponent" "" ""; then
             echo "scientific notation's exponent not integer."
             return 1
         fi
     
     elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
下面的代碼和上面的都同樣了。而後測試下:

./validfloat2.sh 1.0EEe22    
 only one e or E.
 ./validfloat2.sh 1.-3E22
 scientific notation's fractional portion cannot be negative.
 /validfloat2.sh 1.34E-22.35
 錯誤的數字格式!只有數字,不能有逗號、空格等
 scientific notation's exponent not integer.
 ./validfloat2.sh 1.013E22
 1.013E22 is a valid floating-point value
最後,整理下書上的,和本身寫的:

#!/bin/sh

 source validint.sh
 
 validfloat()
 {
     fvalue="$1"
     delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')"
 
     if [ ! -z $delimiter ]; then    #測試下是否有e或E
 
         if [ ${#delimiter} -ne 1 ]; then    #e或E不能有多個
             echo "only one e or E."
             return 1
         fi
         
         decimalPart="$(echo $fvalue | cut -d. -f1)"                #小數點前部分
         part="$(echo $fvalue | cut -d. -f2-)"                    #小數點後部分,注意f2後有一小橫,目的是輸出剩下的全部域
         fractionalPart="$(echo $part | cut "-d$delimiter" -f1)"    #小數點後,e前部分
         exponent="$(echo $part | cut "-d$delimiter" -f2)"        #e後部分
 
         if ! validint "$decimalPart" "-9" "9"; then                #測試小數點前的部分是否是一個數字,即0-9範圍內
             echo "scientific notation's decimal part abs must in [0-9]."
             return 1
         fi
 
         if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then    #測試小數部分第一個符號是否是負號
             echo "scientific notation's fractional portion cannot be negative."
             return 1
         fi
 
         if [ "$fractionalPart" = "" ]; then    #測試小數部分是否是爲空
             echo "scientific notation's fractional portion is empty."
             return 1
         else
             if ! validint "$fractionalPart" "" ""; then        #測試小數部分是否是整數
                 echo "scientific notation's fractional portion is not integer."
                 return 1
             fi
         fi
 
         if ! validint "$exponent" "" ""; then
             echo "scientific notation's exponent not integer."
             return 1
         fi
     
     elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
         
         decimalPart="$(echo $fvalue | cut -d. -f1)"
         fractionalPart="$(echo $fvalue | cut -d. -f2)"
 
         if [ ! -z $decimalPart ]; then
             if ! validint "$decimalPart" "" ""; then
                 return 1
             fi
         fi
 
         if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
             echo "Invalid floating-point number: '-' not allowed \
 after decimal point" >&2
             return 1
         fi
 
         if [ "$fractionalPart" != "" ]; then
             if ! validint "$fractionalPart" "0" ""; then
                 return 1
             fi
         fi
 
         if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then
             if [ -z $fractionalPart ]; then
                 echo "Invalid floating-point format." >&2
             fi
         fi
 
     else
         if [ "$fvalue" = "-" ]; then
             echo "Invalid floating-point format." >&2
             return 1
         fi
 
         if ! validint "$fvalue" "" ""; then
             return 1
         fi
 
     fi
 
     return 0
 }
 
 if validfloat $1; then
     echo "$1 is a valid floating-point value"
 fi
全文完。
相關文章
相關標籤/搜索