ZHAO Xudong
ZHAO Xudong

Reputation: 1411

Convert a byte to a string in Go

I am trying to do something like this:

bytes := [4]byte{1,2,3,4}
str := convert(bytes)

//str == "1,2,3,4"

I searched a lot and really have no idea how to do this.

I know this will not work:

str = string(bytes[:])

Upvotes: 15

Views: 37405

Answers (7)

Jack Copper
Jack Copper

Reputation: 33

The conversion is a bit trickier if you need to convert a null-terminated C character array (a C "string") returned by a legacy C function, to a Go string (which is what I needed to do). Since C arrays do not inherently have a length (C buffer overflows are notorious sources of security issues and bugs), you must manually find the actual 'end' of the C array by finding the location of the first 0 (null) after the C function returns:

bLength = 256 // should be >= the length C function expects
buffer = make([]byte, bLength) // make fixed length byte buffer to pass to C function

someCFunctionThatPutsCharactersIntoBuffer(&buffer[0]) // call the C function, passing address of first byte in buffer

lastPos int = bLength // or lastPos int = len(buffer) - assume buffer is full, possibly without null terminator
for i := range lastPos // C bug may mean buffer is NOT null terminated
    if buffer[i] == 0 {
       lastPos = i      // get true last position
       break
    }
goStringFromC = string(buffer[:lastPos]  // an empty string if lastPos is 0

NOTE that if the C function returns, say, a 32-bit float, you would need to import the binary/encoding and math packages, and after calling the C function use something like:

bits := binary.LittleEndian.Uint32(buffer) // get first 4 bytes of buffer, assuming x86/x64 architecture
var f float32 = math.Float32frombits(bits) // convert raw bits to float32

The same approach works for other numeric values.

Upvotes: 0

digitebs
digitebs

Reputation: 852

func convert( b []byte ) string {
    s := make([]string,len(b))
    for i := range b {
        s[i] = string(b[i])
    }
    return strings.Join(s,",")
}

Upvotes: 0

Sathish
Sathish

Reputation: 1475

using strings.Builder would be the most efficient way to do the same..

package main

import (
  "fmt"
  "strings"
)

func convert( bytes []byte) string {
    var str strings.Builder
    for _, b := range bytes {
       fmt.Fprintf(&str, "%d,", int(b))
    }
    return str.String()[:str.Len() - 1]
}

func main(){
    s := [4]byte{1,2,3,4}
    fmt.Println(convert(s[:]))
}

=> 1,2,3,4

Upvotes: 3

BlockedMan
BlockedMan

Reputation: 21

hex.EncodeToString(input) may work for you.

Upvotes: 1

Dan Garland
Dan Garland

Reputation: 3419

Similar to inf's suggestion but allowing for commas:

fmt.Sprintf("%d,%d,%d,%d", bytes[0], bytes[1], bytes[2], bytes[3])

Upvotes: 12

Didier Spezia
Didier Spezia

Reputation: 73206

Not the most efficient way to implement it, but you can simply write:

func convert( b []byte ) string {
    s := make([]string,len(b))
    for i := range b {
        s[i] = strconv.Itoa(int(b[i]))
    }
    return strings.Join(s,",")
}

to be called by:

bytes := [4]byte{1,2,3,4}
str := convert(bytes[:])

Upvotes: 16

Stephan Dollberg
Stephan Dollberg

Reputation: 34518

If you are not bound to the exact representation then you can use fmt.Sprint:

fmt.Sprint(bytes) // [1 2 3 4]

On the other side if you want your exact comma style then you have to build it yourself using a loop together with strconv.Itoa.

Upvotes: 7

Related Questions