std.debug.print() (Standard Error Output)
In Zig, you can use std.debug.print() to write formatted messages to standard error. It is a function dedicated to debugging — no Writer setup or try propagation is required, making it easy to add debug output quickly. This page covers the syntax, usage, and practical examples of std.debug.print().
Syntax
// -----------------------------------------------
// std.debug.print() — formatted output to stderr
// -----------------------------------------------
std.debug.print(format, args);
// format : format string (must be a compile-time constant string literal)
// args : tuple of format arguments. Pass .{} when there are no arguments
// -----------------------------------------------
// Common format specifiers
// -----------------------------------------------
// {s} — prints a string ([]const u8 or *const [N]u8)
// {d} — prints an integer in decimal
// {f} — prints a floating-point number
// {b} — prints an integer in binary
// {x} — prints an integer in hexadecimal (lowercase)
// {any} — prints any type (for debugging)
// {} — prints using the default format
// -----------------------------------------------
// Example
// -----------------------------------------------
const std = @import("std");
pub fn main() void {
std.debug.print("message: {s}\n", .{"hello"});
std.debug.print("number: {d}\n", .{42});
std.debug.print("multiple: {s} is {d} years old\n", .{"Kiryu", 37});
}
Syntax Reference
| Syntax / Method | Description |
|---|---|
std.debug.print(fmt, args) | Writes a formatted message to stderr. Does not return an error, so try is not needed. |
{s} | Format specifier for string types such as []const u8. |
{d} | Format specifier that prints an integer in decimal. |
{f} | Format specifier that prints a floating-point number. |
{b} | Format specifier that prints an integer in binary. |
{x} | Format specifier that prints an integer in hexadecimal (lowercase). |
{X} | Format specifier that prints an integer in hexadecimal (uppercase). |
{any} | Prints any type using its default representation. Useful for debugging values of unknown type. |
.{} | An empty tuple used when no format arguments are needed. |
.{val1, val2} | Passes multiple format arguments as a tuple. |
Sample Code
print_std.zig
// print_std.zig — example usage of std.debug.print()
// Demonstrates various ways to use formatted debug output
// using characters from Yakuza (Like a Dragon)
// Import the standard library
const std = @import("std");
pub fn main() void {
// -----------------------------------------------
// Basic string output
// -----------------------------------------------
// std.debug.print() writes to stderr
// No try needed; return type is void
std.debug.print("=== Yakuza Character Info ===\n", .{});
std.debug.print("\n", .{});
// -----------------------------------------------
// Embedding strings and integers
// -----------------------------------------------
// Use {s} for strings and {d} for integers
const kiryu_name = "Kiryu Kazuma";
const kiryu_age: u32 = 37;
std.debug.print("Name: {s}\n", .{kiryu_name});
std.debug.print("Age: {d}\n", .{kiryu_age});
std.debug.print("\n", .{});
// -----------------------------------------------
// Printing multiple arguments at once
// -----------------------------------------------
// Place multiple values in a tuple to print them together
const majima_name = "Majima Goro";
const majima_age: u32 = 38;
const nishiki_name = "Nishikiyama Akira";
const nishiki_age: u32 = 27;
std.debug.print("{s} ({d})\n", .{ kiryu_name, kiryu_age });
std.debug.print("{s} ({d})\n", .{ majima_name, majima_age });
std.debug.print("{s} ({d})\n", .{ nishiki_name, nishiki_age });
std.debug.print("\n", .{});
// -----------------------------------------------
// Printing floating-point numbers
// -----------------------------------------------
// Use {f} to print a floating-point number
const haruka_name = "Sawamura Haruka";
const score: f64 = 98.7;
std.debug.print("{s} singing score: {f}\n", .{ haruka_name, score });
std.debug.print("\n", .{});
// -----------------------------------------------
// Printing in hexadecimal and binary
// -----------------------------------------------
// Use {x} for hex and {b} for binary
const date_name = "Date Toshio";
const badge_id: u32 = 1984;
std.debug.print("{s} badge number: {d} (hex: {x}) (bin: {b})\n", .{ date_name, badge_id, badge_id, badge_id });
std.debug.print("\n", .{});
// -----------------------------------------------
// Printing any type with {any}
// -----------------------------------------------
// {any} lets the compiler choose a default representation based on the type
const is_legend: bool = true;
std.debug.print("{s} legend flag: {any}\n", .{ kiryu_name, is_legend });
std.debug.print("\n", .{});
// -----------------------------------------------
// Debugging struct fields one by one
// -----------------------------------------------
// Define a Zig struct
const Character = struct {
name: []const u8,
age: u32,
hp: u32,
};
const characters = [_]Character{
.{ .name = "Kiryu Kazuma", .age = 37, .hp = 1000 },
.{ .name = "Majima Goro", .age = 38, .hp = 950 },
.{ .name = "Sawamura Haruka", .age = 13, .hp = 300 },
.{ .name = "Nishikiyama Akira", .age = 27, .hp = 800 },
.{ .name = "Date Toshio", .age = 45, .hp = 700 },
};
std.debug.print("--- Character List ---\n", .{});
// Iterate over the array with a for loop
for (characters) |chara| {
std.debug.print(" {s}: age={d}, HP={d}\n", .{ chara.name, chara.age, chara.hp });
}
std.debug.print("\nDebug output complete\n", .{});
}
zig run print_std.zig
=== Yakuza Character Info ===
Name: Kiryu Kazuma
Age: 37
Kiryu Kazuma (37)
Majima Goro (38)
Nishikiyama Akira (27)
Sawamura Haruka singing score: 98.7
(Note: the exact output format of {f} may vary depending on the Zig version)
Date Toshio badge number: 1984 (hex: 7c0) (bin: 11111000000)
Kiryu Kazuma legend flag: true
--- Character List ---
Kiryu Kazuma: age=37, HP=1000
Majima Goro: age=38, HP=950
Sawamura Haruka: age=13, HP=300
Nishikiyama Akira: age=27, HP=800
Date Toshio: age=45, HP=700
Debug output complete
Overview
std.debug.print() is a function that writes formatted messages to standard error (stderr). Unlike the approach using std.io.getStdOut().writer(), it requires no Writer setup or try-based error propagation, and its return type is void. This makes it very convenient when you need to quickly inspect values during debugging. The format string must be a compile-time constant, and specifiers such as {s}, {d}, {f}, {x}, {b}, and {any} allow type-appropriate output. Arguments must always be passed as a tuple (.{value, value, ...}). When no arguments are needed, pass an empty tuple .{}. For writing to standard output (stdout), see std.io.getStdOut() (standard output). For details on string formatting, see String Formatting.
If you find any errors or copyright issues, please contact us.