Reputation: 1411
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
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
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
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
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
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
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