Array of bytes to string

strings

#1

Hello,
I get from an external interface an a::Array{UInt32,1} of a fixed length (assume length(a) == 600). This is in principle a buffer. A CString is written into this buffer, last character is \0 and the rest of the array is just a junk. If I do

s = String(a) 

I get a string of lenght 600, although the Cstring is much shorter. Is there a function that would read the array as a Cstring?
I know that during ccall this is done automatically, but I’m obtaining the string byte array from a HDF5 file saved by a different program and I couldn’t find the easy way. Of course I can scan the string byte by byte and than resize it but I feel there is a simple function for it already written, just don’t know its name.
Thank you for the help.


#2

I find it curious that String converts Vector{UInt32} at all, because

julia> a = UInt32.(['a', 'b'])
2-element Array{UInt32,1}:
 0x00000061
 0x00000062

julia> String(a)
ERROR: MethodError: Cannot `convert` an object of type Array{UInt32,1} to an object of type String
This may have arisen from a call to the constructor String(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] String(::Array{UInt32,1}) at ./sysimg.jl:77

#3

I only just started playing around with IO stuff, but here’s my attempt:

# create example problem data
s = "abcdef"
a = rand(UInt32, 600)
writebuf = IOBuffer(reinterpret(UInt8, a), false, true)
write(writebuf, s)
write(writebuf, 0x00) # null-terminate

# create an IOBuffer object that wraps the raw buffer
readbuf = IOBuffer(reinterpret(UInt8, a))

# read to next null
String(readuntil(readbuf, 0x00)) # this includes the \0

#4

My fault, it’s UInt8… My mistake.


#5

You should find the position of the zero (eg findfirst), and either copy the relevant part (eg convert(String, a[1:zeropos])), or return a view to it. You have to think about who manages the memory for the buffer (C? Julia?) and whether you need the string after the buffer is overwritten/freed. See also