#Random characters when writing to FixedBufferStream writer

1 messages · Page 1 of 1 (latest)

golden pebble
#

I'm trying to write a function that converts hundreds of seconds to hours, minutes and seconds. E.g.: 1000 => "10 seconds"



pub fn formatTime(hundreds_of_seconds: u32) ![]const u8 {
    const total_seconds = hundreds_of_seconds / 100;
    const hours = total_seconds / 3600;
    const minutes = (total_seconds / 60) % 60;
    const seconds = total_seconds % 60;

    var buffer: [100]u8 = undefined;
    var fixed_buffer_stream = std.io.fixedBufferStream(&buffer);
    var buffer_writer = fixed_buffer_stream.writer();
    if (hours > 0) {
        try buffer_writer.print("{d} hours, ", .{hours});
    }

    if (minutes > 0) {
        try buffer_writer.print("{d} minutes, ", .{minutes});
    }

    try buffer_writer.print("{d} seconds", .{seconds});

    return buffer[0..];
}

This is where I use the function and print out the return value:


    try stdout.print("Drive time from {d} to {d}: {s}\n", .{ start_node_id, target_node_id, try common.formatTime(dijkstra_drive_time) });

For some reason when I print out the return value, all the data is garbage and semi-random non-printable characters. Is this because the lifetime of the buffer is only within the function scope and it gets deallocated once the function returns replacing that memory space with random bytes? What is the correct way of returning a formatted string ([]const u8)?

white vine
#

For the lifetime of the buffer object, yes.

You would need to move it outside the formatTime(). What you could do is instead pass a buffer like pub fn formatTime(buffer:[]u8, hundreds_of_seconds: u32) ![]const u8. And pass the buffer: [100]u8 there as &buffer.

But the other reason why it prints garbage values is because you're not slicing the undefined parts of the buffer ([0..] means you're just using the whole buffer).
What you would do is instead return buffer[0..fixed_buffer_stream.pos]; I think to get the undefined parts away.

golden pebble
#

Thank you for the suggestion @white vine. I'm having problems with typing the buffer argument though.

pub fn formatTime(buffer: []u8, hundreds_of_seconds: u32)

returns the error:

/snap/zig/8241/lib/std/io/fixed_buffer_stream.zig:128:29: error: invalid type given to fixedBufferStream
                    else => @compileError("invalid type given to fixedBufferStream"),
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/snap/zig/8241/lib/std/io/fixed_buffer_stream.zig:116:66: note: called from here
pub fn fixedBufferStream(buffer: anytype) FixedBufferStream(Slice(@TypeOf(buffer))) {
                                                            ~~~~~^~~~~~~~~~~~~~~~~

And typing the buffer as a pointer to a u8 slice like this:

pub fn formatTime(buffer: *[]u8, hundreds_of_seconds: u32)

I get this error:

main.zig:64:65: error: expected type '*[]u8', found '*[100]u8'
    const dijkstra_formatted_drive_time = try common.formatTime(&dijkstra_time_format_buffer, dijkstra_drive_time);
                                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.zig:64:65: note: pointer type child 'u8' cannot cast into pointer type child '[]u8'
common.zig:15:27: note: parameter type declared here
pub fn formatTime(buffer: *[]u8, hundreds_of_seconds: u32) ![]const u8 {

I also tried passing the buffer in as a slice:

try common.formatTime(&buffer[0..], hundreds_of_seconds);

but I got the error:

main.zig:64:65: error: expected type '*[]u8', found '*const *[100]u8'
    const dijkstra_formatted_drive_time = try common.formatTime(&dijkstra_time_format_buffer[0..], dijkstra_drive_time);
                                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.zig:64:65: note: cast discards const qualifier
common.zig:15:27: note: parameter type declared here
pub fn formatTime(buffer: *[]u8, hundreds_of_seconds: u32) ![]const u8 {
white vine
golden pebble
# white vine You can use the first function where it's `formatTime(buffer: []u8,...)`. No nee...

When I use the function signature formatTime(buffer: []u8, ...) and pass it as &buffer, I get this error:

/snap/zig/8241/lib/std/io/fixed_buffer_stream.zig:128:29: error: invalid type given to fixedBufferStream
                    else => @compileError("invalid type given to fixedBufferStream"),
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/snap/zig/8241/lib/std/io/fixed_buffer_stream.zig:116:66: note: called from here
pub fn fixedBufferStream(buffer: anytype) FixedBufferStream(Slice(@TypeOf(buffer))) {
                                                            ~~~~~^~~~~~~~~~~~~~~~~
#

Oh wait oops my bad

#

I passed the buffer as &buffer in fixedBufferStream. Forgot to change that, thank you!

#

Amazing, it works perfectly now, thanks a lot for your time, I appreciate the help!

mild trellis