英文:
Parse multiple integers from a string in 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地址转换为整数。
你看,我写了这么丑陋的代码。
首先从strconv.Atoi中获取数字,然后将其转换为int64。
如何简化这个过程?
英文:
sorry for the title , i don't know how to say that
i have a questions about this code
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
}
I want to convert an ip address to integer number
you see I have wrote such ugly code
first retrive number from strconv.Atoi then convert it to int64
How to simplify this ?
答案1
得分: 7
如果你想从字符串中解析多个整数,可以尝试使用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])
}
英文:
If you want to parse multiple integers from a string, try the Sscanf function, like this:
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])
}
答案2
得分: 6
这个结构很重,但如果你像你应该的那样捕捉解析错误的话,它看起来更自然。
话虽如此,解决这个问题的正确方法是使用现有的net.ParseIP
函数,它构建了一个IP。
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)。
英文:
This construct is heavy but appears more natural if you, as you probably should, were catching the parsing errors.
This being said, the correct solution to that exact problem is to use the existing net.ParseIP
function which builds an IP
func ParseIP(s string) IP
If you must keep your current function prototype, I suggest this :
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])
}
Note that you may add a test on the return of ParseIP (which is nil in case of error)
答案3
得分: 1
我不建议这样做,因为这样会忽略错误,但你可以编写一个函数来获取第一个值:
func first(x int, _ error) int {return x;}
然后在你的代码中使用 first(strconv.Atoi(p[0]))
。
对于你列出的特定代码,我会使用(经过充分测试的!)标准库的 net.ParseIP() 和 net.To4() 函数:
// 警告:未经测试的代码!!
type InvalidIP string
func (InvalidIP ipStr) Error() string {
return "无效的IPv4地址:" + 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类型是否足够满足你的需求。
英文:
I don't recommend it, because you would be ignoring errors, but you can write a function to give you the first value:
func first(x int, _ error) int {return x;}
Then use first(strconv.Atoi(p[0]))
in your code.
For the particular code you listed though, I would use the (well tested!) standard library's net.ParseIP() and net.To4() functions:
// 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
}
Note that the above code adds error checking, and also accepts IPv6 formatted v4 addresses "::FFFF:C0A8:0101". Consider whether you really need an int64 type to represent IP addresses, or whether the standard library's net.IP type is good enough for your purposes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论