Как преобразовать строку с нулевым символом в байтовый буфер в строку в 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)) } 

Обратите внимание: первый ответ будет работать только со строками, которые имеют нулевой нуль после нулевого терминатора; однако правильная строка с нулевым завершением в стиле C заканчивается с первой \0 даже если за ней следует мусор. Например, []byte{97,98,99,0,99,99,0} должен анализироваться как abc , а не abc^@cc .

Чтобы правильно проанализировать это, используйте string.Index , как string.Index ниже, чтобы найти первый \0 и использовать его для обрезки исходного байтового fragmentа:

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

EDIT: печатал сокращенную версию в виде []byte вместо string . Благодаря @serbaut для улова.

РЕДАКТИРОВАТЬ 2: Не обрабатывал случай ошибки в буфере без нулевого терминатора. Благодаря @snap для улова.

Эта функция скрыта в пакете sysall от Go, который находит первый нулевой байт ([] byte {0}) и возвращает длину. Я предполагаю, что это называется clen для C-Length.

Извините, что я опоздал на этот ответ на год, но я думаю, что это намного проще, чем два других (без лишнего импорта и т. Д.),

 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 с длиной 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».