如何将字节缓冲区中以null结尾的字符串转换为Go中的字符串?

这个:

label := string([]byte{97, 98, 99, 0, 0, 0, 0}) fmt.Printf("%s\n", label) 

这样做( ^@是空字节):

 go run test.go abc^@^@^@ 

使用strings包。

 package main import ( "fmt" "strings" ) func main() { label := string([]byte{97, 98, 99, 0, 0, 0, 0}) fmt.Println(strings.TrimSpace(label)) } 

请注意,第一个答案仅适用于在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])) } 

编辑:将缩短版本打印为[]byte而不是string 。 感谢@serbaut的捕获。

编辑2:没有处理没有空终止符的缓冲区的错误情况。 感谢@snap的捕获。

在Go的syscall包中隐藏了这个函数,它找到第一个空字节([] byte {0})并返回长度。 我假设它被称为C-Length的clen。

对不起,我对这个答案迟了一年,但我认为这比其他两个简单得多(没有不必要的import等)

 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设置为从开头到clen(label)索引的label的字节切片。

结果将是abc ,长度为3。

第一个答案是行不通的!!

 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) } 

func IsSpace中根本没有“\ x00”。