Help converting u8 to string

Not sure if you wanted advice just on the format string, or on the iteration and stream-handling too? Here is the link to std.fmt.format (from master branch) that includes the description of the format string:

The format string must be comptime-known and may contain placeholders following this format: {[argument][specifier]:[fill][alignment][width].[precision]}

[…]

  • d: output numeric value in decimal notation

[…]

To print literal curly braces, escape them by writing them twice, e.g. {{ or }}.

I’m new to Zig too (so not sure if it’s perfect style / idiomatically written), but I gave it a try, including handling generic streams and buffering:

const std = @import("std");

pub fn writePrintable(output: anytype, input: []const u8) !void {
    for (input) |byte| {
        if (byte >= 32 and byte <= 126) {
            try output.writeByte(byte);
        } else {
            try output.print("{{{d:03}}}", .{byte});
        }
    }
}

pub fn main() !void {
    var stdout_bufwriter = std.io.bufferedWriter(std.io.getStdOut().writer());
    var stdout = stdout_bufwriter.writer();
    try writePrintable(stdout, "abc\ndef\n");
    try stdout.print("\n", .{});
    try stdout_bufwriter.flush();
}

Output:

abc{010}def{010}

(using Zig 0.15.0-dev.847+850655f06)