Jaki jest najlepszy sposób na konwersję tablicy bajtów na ciąg znaków?

Muszę przeczytać [100]byte aby przesłać kilka string danych.

Ponieważ nie wszystkie string są dokładnie 100 długie, pozostała część {[3] } jest wyściełana 0 s.

If I tansfer [100]byte to string by: string(byteArray[:]), The tailing 0 S są wyświetlane jako ^@^@ s.

W C string zakończy się po 0, więc zastanawiam się, jaki jest najlepszy sposób mądrego przeniesienia byte array do string.

 390
Author: Bijan, 2013-01-09

11 answers

Metody wczytujące dane do plasterków bajtów zwracają liczbę odczytanych bajtów. Powinieneś zapisać tę liczbę, a następnie użyć jej do utworzenia ciągu znaków. n biorąc pod uwagę liczbę odczytanych bajtów, Twój kod będzie wyglądał następująco:

s := string(byteArray[:n])

Jeśli z jakiegoś powodu nie masz n, możesz użyć pakietu bajtów, aby go znaleźć, zakładając, że Twoje dane wejściowe nie mają w sobie znaku null.

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

Lub jak zauważył icza, możesz użyć poniższego kodu:

n := bytes.IndexByte(byteArray, 0)
 402
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-07 07:25:51

O czym?

s := string(byteArray[:])
 323
Author: mattes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 13:02:40

Uproszczone rozwiązanie:

str := fmt.Sprintf("%s", byteArray)
Nie jestem pewien, czy to jest wydajne.
 41
Author: marcusljx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-02 08:57:14

Na przykład,

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

Wyjście:

C:  100 [97 98 99 0]
Go: 3 abc
 13
Author: peterSO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-09 15:30:00

Poniższy kod szuka '\0' i zgodnie z założeniami pytania tablica może być uznana za posortowaną, ponieważ wszystkie Nie - ' \0 'poprzedzają Wszystkie'\0'. To założenie nie zostanie utrzymane, jeśli tablica może zawierać '\0' w danych.

Znajdź lokalizację pierwszego bajtu zerowego za pomocą wyszukiwania binarnego, a następnie przekrój.

Możesz znaleźć bajt zerowy w następujący sposób:

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

Może być szybsze tylko naiwne skanowanie tablicy bajtów w poszukiwaniu zero-bajtów, zwłaszcza jeśli większość twojego struny są krótkie.

 6
Author: Paul Hankin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-26 14:23:13
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))
}
 3
Author: yuen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-23 05:46:40

Wypróbowałem kilka metod kilka razy wpadłem w panikę:

Runtime error: slice bounds out of range.

Ale to w końcu zadziałało.

string(Data[:])

 2
Author: Gaurav Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 14:50:51

Dlaczego nie to?

bytes.NewBuffer(byteArray).String()
 1
Author: Bhagya Prasad NR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 18:24:13

Jeśli nie znasz dokładnej długości niezerowych bajtów w tablicy, możesz ją najpierw przyciąć:

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

 1
Author: zach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-21 07:02:23
  • Do odczytu używaj plasterków zamiast tablic. np. io.Reader akceptuje wycinek, a nie tablicę.

  • Użyj krojenia zamiast zero padding.

Przykład:

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
Author: zzzz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 11:29:50

I gdy z rozwiązaniem rekurencyjnym.

func CToGoString(c []byte, acc string) string {

    if len(c) == 0 {
        return acc
    } else {
        head := c[0]
        tail := c[1:]
        return CToGoString(tail, acc + fmt.Sprintf("%c", head))
    }
}

func main() {
    b := []byte{some char bytes}
    fmt.Println(CToGoString(b, ""))
}
 -8
Author: Romel Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-06 02:03:20