此:
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Printf("%s\n", label)
这样做(^@
是空字节):
go run test.go
abc^@^@^@
答案 0 :(得分:11)
请注意,第一个答案仅适用于在null终止符后仅运行零的字符串;但是,正确的C样式的以null结尾的字符串在第一个\0
结束,即使它后面是垃圾。例如,[]byte{97,98,99,0,99,99,0}
应该被解析为abc
,而不是abc^@cc
。
要正确解析此问题,请使用string.Index
,如下所示,找到 first \0
并使用它来切片原始字节切片:
package main
import (
"fmt"
"strings"
)
func main() {
label := []byte{97,98,99,0,99,99,0}
nullIndex := strings.Index(string(label), "\x00")
if (nullIndex < 0) {
fmt.Println("Buffer did not hold a null-terminated string")
os.Exit(1)
}
fmt.Println(string(label[:nullIndex]))
}
编辑:将缩短版本打印为[]byte
而不是string
。感谢@serbaut的捕获。
编辑2:没有处理没有空终止符的缓冲区的错误情况。感谢@snap的捕获。
答案 1 :(得分:9)
这个函数隐藏在Go的syscall包中,它找到第一个空字节([] byte {0})并返回长度。我假设它被称为C-Length clen。
对不起我这回答迟了一年,但我觉得它比其他两个更简单很多(没有不必要的进口等)
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
所以,
label := []byte{97, 98, 99, 0, 0, 0, 0}
s := label[:clen(label)]
fmt.Println(string(s))
^所说的是将s
设置为从label
开始到clen(label)
索引的abc
中的字节切片。
结果为{{1}},长度为3。
答案 2 :(得分:5)
使用strings
包。
package main
import (
"fmt"
"strings"
)
func main() {
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Println(strings.TrimSpace(label))
}
答案 3 :(得分:0)
您可以使用 sys
包:
package main
import "golang.org/x/sys/windows"
func main() {
b := []byte{97, 98, 99, 0, 0, 0, 0}
s := windows.ByteSliceToString(b)
println(s == "abc")
}
或者你可以自己实现:
package main
import "bytes"
func byteSliceToString(s []byte) string {
n := bytes.IndexByte(s, 0)
if n >= 0 {
s = s[:n]
}
return string(s)
}
func main() {
b := []byte{97, 98, 99, 0, 0, 0, 0}
s := byteSliceToString(b)
println(s == "abc")
}
答案 4 :(得分:-1)
第一个答案是行不通的!!
func TrimSpace(s []byte) []byte {
return TrimFunc(s, unicode.IsSpace)
}
func IsSpace(r rune) bool {
// This property isn't the same as Z; special-case it.
if uint32(r) <= MaxLatin1 {
switch r {
case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
return true
}
return false
}
return isExcludingLatin(White_Space, r)
}
没有&#34; \ x00&#34;在func IsSpace中。