Formatting specifiers
std.fmt
provides
options for formatting various data types.
From here on, we'll be using std.testing.expectEqualStrings
. This prints out
information if our strings aren't equal, and better conveys our intent over
using std.testing.expect
and std.mem.eql
. It's worth noting that the
"strings" we're operating on are just []const u8
values where we trust that
the buffer is valid UTF-8.
std.fmt.fmtSliceHexLower
and std.fmt.fmtSliceHexUpper
provide hex formatting
for strings as well as {x}
and {X}
for ints.
const std = @import("std");
const eql = std.mem.eql;
const expect = std.testing.expect;
const bufPrint = std.fmt.bufPrint;
const expectEqualStrings = std.testing.expectEqualStrings;
test "hex" {
var b: [10]u8 = undefined;
try expectEqualStrings(
"FFFFFFFE",
try bufPrint(&b, "{X}", .{4294967294}),
);
try expectEqualStrings(
"fffffffe",
try bufPrint(&b, "{x}", .{4294967294}),
);
try expectEqualStrings(
"0xAAAAAAAA",
try bufPrint(&b, "0x{X}", .{2863311530}),
);
try expectEqualStrings(
"5a696721",
try bufPrint(&b, "{}", .{
std.fmt.fmtSliceHexLower("Zig!"),
}),
);
}
{d}
performs decimal formatting for numeric types.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "decimal float" {
var b: [4]u8 = undefined;
try expectEqualStrings(
"16.5",
try bufPrint(&b, "{d}", .{16.5}),
);
}
{c}
formats a byte into an ascii character.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "ascii fmt" {
var b: [1]u8 = undefined;
try expectEqualStrings(
"B",
try bufPrint(&b, "{c}", .{66}),
);
}
std.fmt.fmtIntSizeDec
and std.fmt.fmtIntSizeBin
output memory sizes in
metric (1000) and power-of-two (1024) based notation.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
const fmtIntSizeDec = std.fmt.fmtIntSizeDec;
const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
test "B Bi" {
var b: [32]u8 = undefined;
try expectEqualStrings("1B", try bufPrint(&b, "{}", .{fmtIntSizeDec(1)}));
try expectEqualStrings("1B", try bufPrint(&b, "{}", .{fmtIntSizeBin(1)}));
try expectEqualStrings("1.024kB", try bufPrint(&b, "{}", .{fmtIntSizeDec(1024)}));
try expectEqualStrings("1KiB", try bufPrint(&b, "{}", .{fmtIntSizeBin(1024)}));
try expectEqualStrings(
"1.073741824GB",
try bufPrint(&b, "{}", .{fmtIntSizeDec(1024 * 1024 * 1024)}),
);
try expectEqualStrings(
"1GiB",
try bufPrint(&b, "{}", .{fmtIntSizeBin(1024 * 1024 * 1024)}),
);
}
{b}
and {o}
output integers in binary and octal format.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "binary, octal fmt" {
var b: [8]u8 = undefined;
try expectEqualStrings(
"11111110",
try bufPrint(&b, "{b}", .{254}),
);
try expectEqualStrings(
"376",
try bufPrint(&b, "{o}", .{254}),
);
}
{*}
performs pointer formatting, printing the address rather than the value.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "pointer fmt" {
var b: [16]u8 = undefined;
try expectEqualStrings(
"u8@deadbeef",
try bufPrint(&b, "{*}", .{@as(*u8, @ptrFromInt(0xDEADBEEF))}),
);
}
{e}
outputs floats in scientific notation.
const std = @import("std");
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "scientific" {
var b: [16]u8 = undefined;
try expectEqualStrings(
try bufPrint(&b, "{e}", .{3.14159}),
"3.14159e0",
);
}
{s}
outputs strings.
const std = @import("std");
const eql = std.mem.eql;
const expectEqualStrings = std.testing.expectEqualStrings;
const bufPrint = std.fmt.bufPrint;
test "string fmt" {
var b: [6]u8 = undefined;
const hello: [*:0]const u8 = "hello!";
try expectEqualStrings(
"hello!",
try bufPrint(&b, "{s}", .{hello}),
);
}
This list is non-exhaustive.