2012-06-09 26 views
3

遺憾的標題,我不知道怎麼說,從Go中的字符串解析多個整數?

我有一個關於這個代碼的問題

func ip2long(ip string) (ret int64) { 
    p:= strings.Split(ip, ".") 
    n, _:= strconv.Atoi(p[0]) 
    ret += int64(n)*16777216 
    n, _= strconv.Atoi(p[1]) 
    ret += int64(n)*65536 
    n, _= strconv.Atoi(p[2]) 
    ret += int64(n)*256 
    n, _= strconv.Atoi(p[3]) 
    ret += int64(n) 

    return 
} 

我想轉換一個IP地址整數

你看我已經寫了這樣醜陋的代碼

第一retrive數量從strconv.Atoi然後將其轉換爲int64

如何送這意味着什麼?

回答

6

如果你想從一個字符串解析多個整數,試試sscanf函數,就像這樣:

func main() { 
    var ip [4] uint32 
    addr := "192.168.0.1" 
    _, err := fmt.Sscanf(addr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) 
    if err != nil { 
     fmt.Println(err) 
     return 
    } 
    fmt.Println(ip) 
    fmt.Println(ip[0]<<24 + ip[1]<<16 + ip[2]<<8 + ip[3]) 
} 
+1

sscanf的返回一個錯誤,這是這裏被忽略。正如其他答案強調錯誤檢查的重要性一樣,最好在這裏檢查Sscanf的結果。 – Sonia

6

這個構造很沉重,但如果你可能會捕捉解析錯誤,那麼看起來更自然。

這是說,正確的解決方案,準確的問題是使用現有的net.ParseIP功能,構建了一個​​

func ParseIP(s string) IP 

如果一定要保持當前的函數原型,我的建議是:

func ip2long(s string) (ret int64) { 
    bip := ([]byte)(net.ParseIP(s).To4()) 
    return (int64)(bip[0]) * (1 << 24) + (int64)(bip[1]) * (1 << 16) + (int64)(bip[2]) * (1 << 8) + (int64)(bip[3]) 
} 

請注意,您可能會添加一個測試返回ParseIP(這是nil在出錯的情況下)

1

我不記得mmend它,因爲你會被忽略的錯誤,但你可以編寫一個函數來給你的第一個值:

func first(x int, _ error) int {return x;} 

在你的代碼,然後使用first(strconv.Atoi(p[0]))

對於你,儘管列出的特定代碼,我會用(很好的測試!)標準庫的net.ParseIP()和net.To4()函數:

// WARNING untested code!! 

type InvalidIP string 
func (InvalidIP ipStr) Error() string { 
    return "Invalid IPv4 address: "+ipStr 
} 

func ip2long(ipStr string) (ret int64, err error) { 
    var ip net.IP 
    if ip = net.ParseIP(ipStr); ip == nil { 
     return 0, InvalidIP(ip) 
    } 
    if ip = ip.To4(); ip == nil { 
     return 0, InvalidIP(ip) 
    } 
    for b := range ip { 
     ret <<= 8 
     ret += b 
    } 
    return ret, nil 
} 

注意上面的代碼增加錯誤檢查,並且還接受IPv6格式化的v4地址「:: FFFF:C0A8:0101」。考慮你是否真的需要一個int64類型來表示IP地址,或者標準庫的net.IP類型是否足夠滿足你的需求。