Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I print a vector of u8 as a string?

Tags:

Here's my code:

let mut altbuf: Vec<u8> = Vec::new();

// Stuff here...

match stream.read_byte() {
    Ok(d) => altbuf.push(d),
    Err(e) => { println!("Error: {}", e); doneflag = true; }
}

for x in altbuf.iter() {
    println!("{}", x);
}

The code prints u8 bytes which are correct, but I can't figure out for the life of me how to convert a vector of pure u8 bytes into a string? The only other answer to a similar question on stack overflow assumes that you're working with a vector of type &[u8].

like image 434
AAnderson Avatar asked Jan 24 '15 09:01

AAnderson


2 Answers

If you look at the String documentation, there are a few methods you could use. There's String::from_utf8 that takes a Vec<u8>, and there's also String::from_utf8_lossy which takes a &[u8].

Note that a Vec<T> is more-or-less an owned, resizable wrapper around a [T]. That is, if you have a Vec<u8>, you can turn it into a &[u8], most easily by re-borrowing it (i.e. &*some_vec). You can also call any methods defined on &[T] directly on a Vec<T> (in general, this is true of things that implement the Deref trait).

like image 52
DK. Avatar answered Sep 20 '22 19:09

DK.


If your altbuf is a vector of u8 as shown, this should work:

println!("{:?}", altbuf);

Here is an edited piece of code I have that does something similar:

let rebuilt: Vec<u8>;

unsafe {
    ret = proc_pidpath(pid, buffer_ptr, buffer_size);
    rebuilt = Vec::from_raw_parts(buffer_ptr as *mut u8, ret as usize, buffer_size as usize);
};

println!("Returned a {} byte string", ret);
println!("{:?}", rebuilt);

That rebuilds a vector of u8 values from a buffer filled by a C function called via FFI so the bytes could be anything, maybe not valid UTF-8.

When I run it, the output is:

Returned a 49 byte string

[47, 85, 115, 101, 114, 115, 47, 97, 110, 100, 114, 101, 119, 47, 46, 114, 98, 101, 110, 118, 47, 118, 101, 114, 115, 105, 111, 110, 115, 47, 49, 46, 57, 46, 51, 45, 112, 51, 57, 50, 47, 98, 105, 110, 47, 114, 117, 98, 121]

You could format the numbers printed (in hex, octal, etc) using different format strings inside the {}.

You can get a String from that using String::from_utf8(rebuilt) - which may return an error.

match String::from_utf8(rebuilt) {
    Ok(path) => Ok(path),
    Err(e) => Err(format!("Invalid UTF-8 sequence: {}", e)),
}
like image 35
Andrew Mackenzie Avatar answered Sep 17 '22 19:09

Andrew Mackenzie