#Proper way to format null terminated strings

1 messages · Page 1 of 1 (latest)

rapid spire
#

I have a struct

Struct {
    Username: [32:0]u8,
    Email: [65:0]u8
}

When I check the contents it's 'biom4st3r\0' followed by 0xaa's, but when I print it via client.stream.writer().print("{s}", .{data.username}) ,with client being a StreamServer.Connection, it comes out as biom4st3r followed by a bunch of Unicode junk.

I have a function that just returns a slice ending at the sentinel, but I thought I had it working earlier without the function

willow surge
#

does client.stream.writer().print("{s}", .{&data.username}) work?

rapid spire
#

I also tried that and got the same result

valid path
#

[32:0]u8 is 32 u8s followed by a guarateed 0, if you only want up to the first zero, use std.mem.sliceTo()

willow surge
#

whats funny is that this works: std.debug.print("{s}\n", .{@as([*:0]u8, &str)});, but thats just cuz it calls std.mem.span for you lol

#

sliceTo is def the way to go tho

rapid spire
#

It just seems strange that fmt wouldnt take the sentinel into account

valid path
#

the sentinel is only guaranteed to be at the last index

#

a sentinel terminated slice or array is allowed to contain the sentinel as part of it's content, because the length is independently known

rapid spire
#

It's not just printing the sentinel. It's printing the whole buffer including everything after the sentinel

valid path
#

it's printing the entire array, again, the array doesn't end at the first sentinel

tall grove
#

This is an important distinction between sentineled arrays and sentineled pointers like [*:0]u8. The latter type just has a semantic meaning of "I promise there will be a sentinel 0 at some point", whereas sentineled arrays are actually different in memory to non-sentineled arrays: they store an extra element

#

[10:0]u8 is like a [11]u8 but Zig makes sure that the last element (arr[10]) is initialized to 0