这个:
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Printf("%s\n", label)
Run Code Online (Sandbox Code Playgroud)
这^@
是(是空字节):
go run test.go
abc^@^@^@
Run Code Online (Sandbox Code Playgroud)
aze*_*nik 11
请注意,第一个答案仅适用于在null终止符后仅运行零的字符串; 然而,一个正确的C风格的以null结尾的字符串在第一个字符串结尾,\0
即使它后面跟着垃圾.例如,[]byte{97,98,99,0,99,99,0}
应该解析为abc
,而不是abc^@cc
.
要正确解析它,请string.Index
按如下方式使用以查找第一个 \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]))
}
Run Code Online (Sandbox Code Playgroud)
编辑:打印缩短版本[]byte
而不是作为string
.感谢@serbaut的捕获.
编辑2:没有处理没有空终止符的缓冲区的错误情况.感谢@snap的捕获.
在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)
}
Run Code Online (Sandbox Code Playgroud)
所以,
label := []byte{97, 98, 99, 0, 0, 0, 0}
s := label[:clen(label)]
fmt.Println(string(s))
Run Code Online (Sandbox Code Playgroud)
^所说的是设置s
为label
从开头到索引的字节切片clen(label)
.
结果将是abc
3的长度.
使用strings
包.
package main
import (
"fmt"
"strings"
)
func main() {
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Println(strings.TrimSpace(label))
}
Run Code Online (Sandbox Code Playgroud)