Converting String to an array of u8

Hi,

I need to convert a String from user input into an array of u8.

I've read that arrays of u8 implement Write from std::io::Write so I'm trying to do that...

fn main() {
    let un = "test";
    
    let mut test: &mut[u8] = &mut[0;32];
    test.write(un.as_bytes()).unwrap();
    
    println!("Test: {:?}", test);
}

But the resulting array doesn't seem to have changed, am I missing something on this?

Test: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Writing to a mutable reference changes which part of the slice it points at.

use std::io::Write;

fn main() {
    let un = "test";
    
    let mut buffer = [0; 32];
    let mut test: &mut[u8] = &mut buffer;
    test.write(un.as_bytes()).unwrap();
    
    println!("{} + {} = {}", un.len(), test.len(), buffer.len());
    println!("Test: {:?}", buffer);
}
1 Like

If you look closer at the output, it's not 32 zeroes there, but only 28, which is what remains after using four of the bytes to write "test".

What you can to is to write to a temporary reference, and then check the original reference, something like this:

    let mut test = [0u8; 32];
    {
        let mut test = &mut test[..];
        test.write(un.as_bytes()).unwrap();
    }
    println!("Test: {:?}", test);
Edit: The part hidden here was just wrong

Which you can actually write as:

    let mut test = [0; 32];
    test.write(un.as_bytes()).unwrap();
    println!("Test: {:?}", test);

... which seems very similar to what you originally did, the difference is that "test" here is the actual array and not a slice of it, so calling a slice method on it will dereference the array to a temporary slice, and write to that. It then drops the slice (but keeps the array), which is forgetting where the "cursor" is after writing but keeping the buffer you write to.

2 Likes

BTW, it's always an error to use write() outside of a retrying loop. This method is unreliable by design doesn't guarantee that it writes what you've given it. I don't recommend ever using write(). Use write_all() instead.

9 Likes

Also, you may want to convert the heap-allocated String to a Vec<u8>, which is a heap-allocated resizable array. That can be done by calling un.into_bytes(). That will not do any allocation or copy any data, it will just tell the compiler that the allocated data that it used to refer to as a String is now a Vec<u8>.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.