it-swarm.com.de

Wie konvertiere ich ein nullterminiertes Byte-Array in einen String?

Ich muss [100]byte Lesen, um eine Reihe von string Daten zu übertragen.

Da nicht alle strings genau 100 Zeichen lang sind, wird der verbleibende Teil des byte array Mit 0 Aufgefüllt.

Wenn ich [100]byte Per: string(byteArray[:]) an string überweise, werden die Tailing-Werte 0 Als ^@^@ Angezeigt.

In C endet das string mit 0, Daher frage ich mich, wie man ein byte array Am besten nach string in Golang überträgt.

468
Derrick Zhang

methoden, die Daten in Byte-Slices lesen, geben die Anzahl der gelesenen Bytes zurück. Sie sollten diese Nummer speichern und dann verwenden, um Ihre Zeichenfolge zu erstellen. n Wenn Sie die Anzahl der gelesenen Bytes angeben, sieht Ihr Code folgendermaßen aus:

s := string(byteArray[:n])

Wenn Sie aus irgendeinem Grund nicht n haben, können Sie das Byte-Paket verwenden, um es zu finden, vorausgesetzt, Ihre Eingabe enthält kein Nullzeichen.

n := bytes.Index(byteArray, []byte{0})

Oder wie icza betonte, können Sie den folgenden Code verwenden:

n := bytes.IndexByte(byteArray, 0)
478
Daniel

Wie wäre es mit?

s := string(byteArray[:])
368
mattes

Einfache Lösung:

str := fmt.Sprintf("%s", byteArray)

Ich bin mir nicht sicher, wie performant das ist.

61
marcusljx

Zum Beispiel,

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

Ausgabe:

C:  100 [97 98 99 0]
Go: 3 abc
13
peterSO

Der folgende Code sucht nach '\ 0', und unter den Voraussetzungen der Frage kann das Array als sortiert betrachtet werden, da alle Nicht-'\ 0' vor allen '\ 0' stehen. Diese Annahme wird nicht gelten, wenn das Array '\ 0' in den Daten enthalten kann.

Suchen Sie die Position des ersten Null-Bytes mithilfe einer binären Suche und schneiden Sie sie anschließend.

Sie können das Null-Byte wie folgt finden:

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

Es ist möglicherweise schneller, wenn Sie das Byte-Array nur naiv nach dem Null-Byte durchsuchen, insbesondere wenn die meisten Ihrer Zeichenfolgen kurz sind.

6
Paul Hankin

Wenn Sie die genaue Länge von Nicht-Null-Bytes im Array nicht kennen, können Sie diese zuerst kürzen:

string (bytes.Trim (arr, "\ x00"))

3
zach

Nur zur Leistungsoptimierung verwenden.

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

func BytesToString(b []byte) string {
    bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    sh := reflect.StringHeader{bh.Data, bh.Len}
    return *(*string)(unsafe.Pointer(&sh))
}

func StringToBytes(s string) []byte {
    sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
    bh := reflect.SliceHeader{sh.Data, sh.Len, 0}
    return *(*[]byte)(unsafe.Pointer(&bh))
}

func main() {
    b := []byte{'b', 'y', 't', 'e'}
    s := BytesToString(b)
    fmt.Println(s)
    b = StringToBytes(s)
    fmt.Println(string(b))
}
2
yuen

Warum nicht das?

bytes.NewBuffer(byteArray).String()
1

Ich habe einige Methoden ausprobiert, einige Male bekam ich Panik:

laufzeitfehler: Segmentgrenzen außerhalb des Bereichs.

Aber das hat endlich geklappt.

string(Data[:])

0
Gaurav Singh
  • Verwenden Sie zum Lesen Slices anstelle von Arrays. z.B. io.Reader akzeptiert ein Slice, kein Array.

  • Verwenden Sie Slicing anstelle von Zero-Padding.

Beispiel:

_buf := make([]byte, 100)
n, err := myReader.Read(buf)
if n == 0 && err != nil {
        log.Fatal(err)
}

consume(buf[:n]) // consume will see exact (not padded) slice of read data
_
0
zzzz