我需要读取[100]字节来传输一堆字符串数据。
因为不是所有的字符串都恰好是100个字符长,所以字节数组的其余部分用0填充。
如果我通过:string(byteArray[:])将[100]字节转换为字符串,则后面的0将显示为^@^@s。
在C语言中,字符串将在0处终止,那么在Go中将这个字节数组转换为字符串的最佳方法是什么?
我需要读取[100]字节来传输一堆字符串数据。
因为不是所有的字符串都恰好是100个字符长,所以字节数组的其余部分用0填充。
如果我通过:string(byteArray[:])将[100]字节转换为字符串,则后面的0将显示为^@^@s。
在C语言中,字符串将在0处终止,那么在Go中将这个字节数组转换为字符串的最佳方法是什么?
当前回答
下面的代码正在寻找'\0',在这个问题的假设下,数组可以被认为是排序的,因为所有非'\0'在所有'\0'之前。如果数组可以在数据中包含“\0”,那么这个假设就不成立了。
使用二进制搜索找到第一个零字节的位置,然后切片。
你可以像这样找到零字节:
package main
import "fmt"
func FirstZero(b []byte) int {
min, max := 0, len(b)
for {
if min + 1 == max { return max }
mid := (min + max) / 2
if b[mid] == '\000' {
max = mid
} else {
min = mid
}
}
return len(b)
}
func main() {
b := []byte{1, 2, 3, 0, 0, 0}
fmt.Println(FirstZero(b))
}
简单地扫描字节数组寻找零字节可能会更快,特别是如果您的大多数字符串都很短。
其他回答
Use:
s := string(byteArray[:])
简单的解决方案:
str := fmt.Sprintf("%s", byteArray)
但我不确定它的性能如何。
下面是一个删除空字节的选项:
package main
import "golang.org/x/sys/windows"
func main() {
b := []byte{'M', 'a', 'r', 'c', 'h', 0}
s := windows.ByteSliceToString(b)
println(s == "March")
}
https://pkg.go.dev/golang.org/x/sys/unix#ByteSliceToString https://pkg.go.dev/golang.org/x/sys/windows#ByteSliceToString
用这个:
bytes.NewBuffer(byteArray).String()
例如,
package main
import "fmt"
func CToGoString(c []byte) string {
n := -1
for i, b := range c {
if b == 0 {
break
}
n = i
}
return string(c[:n+1])
}
func main() {
c := [100]byte{'a', 'b', 'c'}
fmt.Println("C: ", len(c), c[:4])
g := CToGoString(c[:])
fmt.Println("Go:", len(g), g)
}
输出:
C: 100 [97 98 99 0]
Go: 3 abc