to:Jak przekonwertować łańcuch zakończony znakiem NUL w buforze bajtów na ciąg w Go?
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Printf("%s\n", label)
czyni to (^@
jest zerowa bajt)
go run test.go
abc^@^@^@
to:Jak przekonwertować łańcuch zakończony znakiem NUL w buforze bajtów na ciąg w Go?
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Printf("%s\n", label)
czyni to (^@
jest zerowa bajt)
go run test.go
abc^@^@^@
użyciu pakietu strings
.
package main
import (
"fmt"
"strings"
)
func main() {
label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Println(strings.TrimSpace(label))
}
Użyłem 'stringów.TrimRight (label," \ x00 ")', dzięki! – knarf
Zauważ, że pierwsza odpowiedź będzie działać tylko z łańcuchów, które mają tylko serię zer po zerowej terminatora; jednakże prawidłowy łańcuch zakończony znakiem C kończy się na pierwszym \0
, nawet jeśli następuje po nim śmieci. Na przykład []byte{97,98,99,0,99,99,0}
należy przeanalizować jako , a nie abc^@cc
.
Aby poprawnie analizować to, użyj string.Index
, w następujący sposób, aby znaleźć pierwszy\0
i używać go kroić oryginalny bajt kawałek:
package main
import (
"fmt"
"strings"
)
func main() {
label := []byte{97,98,99,0,99,99,0}
s := label[:strings.Index(string(label), "\x00")]
fmt.Println(string(s))
}
EDIT: Czy drukowanie skróconej wersji jako []byte
zamiast jako string
. Dzięki @serbaut za połów.
Ta funkcja jest ukryta w pakiecie syscall Go, która znajduje pierwszy bajt zerowy ([] Bajt {0}) i zwraca jego długość. Zakładam, że nazywa się clen dla C-Length.
Niestety jestem rok późno na tej odpowiedzi, ale myślę, że to dużo prostsze niż dwóch pozostałych (bez zbędnych importu, itp)
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
Więc
label := []byte{97, 98, 99, 0, 0, 0, 0}
s := label[:clen(label)]
fmt.Println(string(s))
To, co^mówi, to ustawić s
na kawałek bajtów w label
od początku do indeksu clen(label)
.
Wynik byłby abc
o długości 3.
Jest to w rzeczywistości najczystsze, najprostsze i bardziej wydajne rozwiązanie. –
I, w przeciwieństwie do odpowiedzi 'string.Index', nie będzie panikuj, jeśli podany bajt' [] nie * zawiera * zero bajtów. –
Pierwsza odpowiedź nie będzie działać !!
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)
}
Nie ma "\ x00" w func IsSpace w ogóle.
Podobał mi się twój rozbudowany tytuł pytania. Byłem jednak rozczarowany pytaniami tekstowymi. (Zapewnia jednak użyteczny kod, dam ci to.) – Kissaki