string बाइट सरणी को स्ट्रिंग में कनवर्ट करने का सबसे अच्छा तरीका क्या है?




go byte (9)

यह क्यों नहीं?

bytes.NewBuffer(byteArray).String()

string डेटा का एक गुच्छा स्थानांतरित करने के लिए मुझे [100]byte पढ़ने की जरूरत है।

चूंकि सभी string ठीक से 100 लंबे नहीं हैं, byte array का शेष भाग 0 एस के साथ गद्देदार है।

यदि मैं string(byteArray[:]) द्वारा string करने के लिए [100]byte को तब्दील करता हूं, तो पूंछ 0 को ^@^@ एस के रूप में प्रदर्शित किया जाता है।

सी में string 0 पर समाप्त हो जाएगी, इसलिए मुझे आश्चर्य है कि string byte array को स्मार्ट रूप से स्थानांतरित करने का सबसे अच्छा तरीका क्या है।


व्हाट अबाउट?

s := string(byteArray[:])

सरल समाधान:

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

मुझे यकीन नहीं है कि यह कितना सक्षम है।


जब मैं एक पुनरावर्ती समाधान के साथ।

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

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

निम्नलिखित कोड '\ 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))
}

शून्य-बाइट की तलाश में बाइट सरणी को आसानी से स्कैन करने के लिए यह तेज़ी से हो सकता है, खासकर यदि आपके अधिकांश तार कम हैं।


मैंने कुछ तरीकों की कोशिश की, मुझे घबराहट मिली:

रनटाइम त्रुटि: रेंज सीमा से बाहर सीमाएं।

लेकिन अंततः यह काम किया।

string(Data[:])


बाइट स्लाइस में डेटा पढ़ने वाले विधियों को पढ़ने वाले बाइट्स की संख्या लौटाती है। आपको उस नंबर को सहेजना चाहिए और फिर अपनी स्ट्रिंग बनाने के लिए इसका उपयोग करना चाहिए। n बाइट्स पढ़ने की संख्या होने के नाते, आपका कोड इस तरह दिखेगा:

s := string(byteArray[:n])

अगर किसी कारण से आपके पास n नहीं है, तो आप इसे खोजने के लिए बाइट्स पैकेज का उपयोग कर सकते हैं, मानते हैं कि आपके इनपुट में इसका कोई शून्य चरित्र नहीं है।

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

या जैसा कि आईसीज़ा ने बताया, आप नीचे दिए गए कोड का उपयोग कर सकते हैं:

n := bytes.IndexByte(byteArray, 0)

  • पढ़ने के लिए सरणी के बजाय स्लाइस का प्रयोग करें। उदाहरण के लिए io.Reader एक टुकड़ा स्वीकार करता है, एक सरणी नहीं।

  • शून्य पैडिंग के बजाय स्लाइसिंग का प्रयोग करें।

उदाहरण:

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




byte