8

这个:

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

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

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

5 回答 5

15

这个函数隐藏在 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字节片。labelclen(label)

结果将是abc长度为 3。

于 2015-01-08T07:19:24.600 回答
12

请注意,第一个答案仅适用于在 null 终止符之后只有一系列零的字符串;然而,一个适当的 C 风格的以空字符结尾的字符串会在第一个结尾结束,\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]))
}

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

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

于 2012-09-11T20:36:22.857 回答
3

使用该strings软件包。

package main

import (
    "fmt"
    "strings"
)

func main() {
    label := string([]byte{97, 98, 99, 0, 0, 0, 0})
    fmt.Println(strings.TrimSpace(label))
}
于 2012-09-10T21:34:40.800 回答
1

您可以使用该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")
}
于 2021-04-22T18:08:19.813 回答
-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)
}

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

于 2017-03-24T06:42:23.083 回答