# "null" bytes outputted when building formatted string

**URL:** <https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169>\
**Category:** Help\
**Created:** [May 5, 2022, 9:40pm UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169 "2022-05-05T21:40:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![GarrettTypes](https://ziggit.dev/user_avatar/ziggit.dev/garretttypes/32/138_2.png) [@GarrettTypes](https://ziggit.dev/u/GarrettTypes)\
**Post date:** [May 5, 2022, 9:40pm UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/1 "2022-05-05T21:40:15Z")

</div>

Hey gang,

I’m still just getting started with Zig but I noticed something odd about some formatting code I wrote. I figured it would be worth sharing to see what you all think.

Given the following code:

```zig
const std = @import("std");
pub fn main() void {
    // (negative example) works fine
    std.log.info("{s}", .{"Testing"});

    // build a string from a pre-defined buffer
    var str : [32]u8 = undefined;
    _ = std.fmt.bufPrint(str[0..], "Testing", .{}) catch {};

    // (positive example) 0xaa chars included
    std.log.info("{s}", .{str});
}

```

We get the following output when piped to hexdump. (Notice all the `aa` bytes)

```zig
$ zig build-exe test.zig
$ ./test 2>&1 | hexdump -C
00000000 69 6e 66 6f 3a 20 54 65 73 74 69 6e 67 0a 69 6e |info: Testing.in|
00000010 66 6f 3a 20 54 65 73 74 69 6e 67 aa aa aa aa aa |fo: Testing.....|
00000020 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................|
00000030 aa aa aa aa 0a |.....|
00000035

```

Essentially, this seems like formatted string parameters will always output the full length of the given string. For const strings this would be totally fine because the end of the array is the end of the string, but for dynamic ones it can lead to extra output.

I kinda wonder if this is something that is just overlooked because non-unicode terminals completely skip these characters.

So the question is, should these formatting functions check for these `aa` bytes and consider that the end of string? Or is this method of constructing strings just a bad practice that should be avoided?

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [May 6, 2022, 12:05am UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/2 "2022-05-06T00:05:06Z")

</div>

`std.fmt.bufPrint` prints to the buffer you pass in, and returns a slice of that buffer that contains what was actually printed. In your code, you’re ignoring this returned slice and instead printing the full buffer `str`, so Zig does exactly that. Check out this version:

```zig
const std = @import("std");

pub fn main() void {
    // (negative example) works fine
    std.log.info("{s}", .{"Testing"});

    // build a string from a pre-defined buffer
    var str: [32]u8 = undefined;
    const out = std.fmt.bufPrint(&str, "Testing", .{}) catch unreachable;

    // (positive example) 0xaa chars included
    std.log.info("{s}, {}", .{ str, str.len });
    std.log.info("{s}, {}", .{ out, out.len });
}

```

output:

```zig
info: Testing
info: Testing, 32
info: Testing, 7

```

---

<div class="post-metadata">

**Author:** ![GarrettTypes](https://ziggit.dev/user_avatar/ziggit.dev/garretttypes/32/138_2.png) [@GarrettTypes](https://ziggit.dev/u/GarrettTypes)\
**Post date:** [May 6, 2022, 12:21am UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/3 "2022-05-06T00:21:01Z")

</div>

Ahh, that makes sense. I thought `bufPrint` only returned the length of what it changed, not a slice of the updated string.

That seems smarter, just a little unintuitive compared to the standard null-terminated strings we usually see.

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [May 6, 2022, 12:33am UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/4 "2022-05-06T00:33:57Z")

</div>

Yeah, all things strings in Zig may take a little getting used to, but once you get the hang of it, there’s a lot of power and flexibility in the way Zig does it. To make the intent more clear, I would recommend renaming the variables like so:

```zig
var buf: [32]u8 = undefined;
const str = std.fmt.bufPrint(&buf, "Testing", .{}) catch unreachable;

```

---

<div class="post-metadata">

**Author:** ![GarrettTypes](https://ziggit.dev/user_avatar/ziggit.dev/garretttypes/32/138_2.png) [@GarrettTypes](https://ziggit.dev/u/GarrettTypes)\
**Post date:** [May 6, 2022, 1:46am UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/5 "2022-05-06T01:46:28Z")

</div>

I actually solved my original problem by circumventing the local buffer entirely. Now I just merge the format strings and arguments at compile-time and feed it all to a single call. That’s what I wanted initially, but there’s a lot of syntax to search through.

Here’s what my code looks like now.

```zig
const std = @import("std");
const SourceLocation = std.builtin.SourceLocation;

pub inline fn info(
    comptime src: SourceLocation,
    comptime msgFormat: []const u8,
    msgArgs:anytype) void
{
    const fullFormat = "[{s}:{d}] " ++ msgFormat;
    var fullArgs = .{std.fs.path.basename(src.file), src.line} ++ msgArgs;
    std.log.info( fullFormat, fullArgs);
}

pub fn main() void {
    info(@src(), "Hello {s}", .{"Zig!"});
    // outputs: info: [test2.zig:15] Hello Zig!
}

```

---

<div class="post-metadata">

**Author:** ![InKryption](https://ziggit.dev/user_avatar/ziggit.dev/inkryption/32/113_2.png) [@InKryption](https://ziggit.dev/u/InKryption)\
**Post date:** [May 7, 2022, 3:39pm UTC](https://ziggit.dev/t/null-bytes-outputted-when-building-formatted-string/169/6 "2022-05-07T15:39:17Z")

</div>

@GarrettTypes in case it is of interest to you at all, I’d also like to point out the existence of `std.fmt.comptimePrint`.
