How to prints 26 bytes in hex on a single line?

Following is a tcp server code reading data from my tcp client serial to ethernet board and storing on a mutable buffer and printing. I wrote this code with the help of this article. (How to Build a Client Server Application using Rust | Engineering Education (EngEd) Program | Section) - credit to the author.

let mut buf = [0;26];
for _ in 0..200{
    let bytes_read = stream.read(&mut buf)?;
    println!("Bytes read {}", bytes_read);
    
    stream.write(&buf[..bytes_read])?;
    **println!("from the sender:{:#?}",buf);**
    thread::sleep(time::Duration::from_secs(1));  
}

How to print all the 26 bytes as hex in a single line after space?

This now prints as below:
Bytes read 26
from the sender:[
172,
181,
177,
178,
190,
162,
169,
179,
163,
166,
138,
141,
128,
167,
181,
172,
179,
191,
189,
165,
180,
191,
172,
165,
161,
178,

Like this, maybe? I don't quite understand what you mean by "after space".

fn main() {
    let bytes: [u8; 26] = [0xF0; 26];
    
    for b in &bytes {
        print!("{b:02X} ");
    }

    println!();
}

Stdout:

F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 

Playground.

2 Likes

Maybe you should also add a println!() call to the end, so that the next outputs will be on a separate line.

1 Like

You are right, I added it to the snippet.

You likely should use print!("{b:02X} ");, otherwise on 0x0F you will get F F F F F. Also I would note that from performance point of view printing hex-encoding of every byte is far from efficient.

Great point, updated the example.

What would your alternative look like? Do you think this:

fn main() {
    let bytes: [u8; 26] = [0xF0; 26];
    
    println!("{bytes:02X?}");
}

will be faster? Or do you have a completely different approach in mind?

The fastest way would be to encode &[u8; N] into [u8; 3*N] (2*N hex chars, N-1 spaces, and one \n) and write the resulting buffer into stdout.

1 Like

But this shouldn't make any practical difference for line-buffered IO, right?

There is no practical difference on such toy exercise in the first place. I mentioned it because on less toy problems it may matter.

There are two parts to consider:

  • Encoding efficiency. println! and format! will be less efficient than encoding into a stack-allocated fixed-size buffer. At the very least the latter removes dynamic dispatch currently used by Rust formatting machinery (it may change in future, but for now it is what it is), which allows compiler to perform various optimizations.
  • Number of write syscalls. Using one write call is better than many. And with print!ing every byte you also pay unnecessary locking cost.
1 Like

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.