Zig Standard Library

The Zig standard library provides battle-tested implementations of common programming needs: collections, string handling, file I/O, networking, JSON parsing, random numbers, sorting, and more. Every module is imported through std and uses the same allocator pattern you have already learned.

Importing and Navigating std

const std = @import("std");

// Common namespaces:
// std.mem      → memory operations (compare, copy, search)
// std.fmt      → formatting and parsing numbers/strings
// std.fs       → file system (open, read, write files)
// std.io       → input/output streams
// std.math     → mathematical functions
// std.sort     → sorting algorithms
// std.time     → timestamps and sleep
// std.json     → JSON parse and stringify
// std.crypto   → hashing, encryption
// std.net      → networking
// std.heap     → allocators
// std.testing  → test utilities

std.mem — Memory and String Operations

const std = @import("std");

pub fn main() void {
    const a = "Hello, Zig!";
    const b = "Hello, Zig!";

    // Compare two slices
    std.debug.print("Equal: {}\n", .{std.mem.eql(u8, a, b)});  // true

    // Find a substring
    if (std.mem.indexOf(u8, a, "Zig")) |pos| {
        std.debug.print("Found 'Zig' at index {d}\n", .{pos});  // 7
    }

    // Check prefix and suffix
    std.debug.print("Starts with Hello: {}\n",
        .{std.mem.startsWith(u8, a, "Hello")});  // true
    std.debug.print("Ends with !: {}\n",
        .{std.mem.endsWith(u8, a, "!")});          // true

    // Count occurrences
    const count = std.mem.count(u8, "zig zig zig", "zig");
    std.debug.print("Count: {d}\n", .{count});  // 3
}

std.fmt — Formatting and Parsing

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Format a string into a heap-allocated buffer
    const msg = try std.fmt.allocPrint(allocator, "Score: {d}/{d}", .{88, 100});
    defer allocator.free(msg);
    std.debug.print("{s}\n", .{msg});  // Score: 88/100

    // Format into a fixed-size stack buffer
    var buf: [64]u8 = undefined;
    const s = try std.fmt.bufPrint(&buf, "Pi = {d:.4}", .{3.14159});
    std.debug.print("{s}\n", .{s});  // Pi = 3.1416

    // Parse a string into an integer
    const n = try std.fmt.parseInt(i32, "42", 10);
    std.debug.print("Parsed: {d}\n", .{n});  // 42

    // Parse a float
    const f = try std.fmt.parseFloat(f64, "3.14");
    std.debug.print("Float: {d}\n", .{f});   // 3.14
}

std.fs — File System

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Write a file
    const file = try std.fs.cwd().createFile("output.txt", .{});
    defer file.close();
    try file.writeAll("Hello from Zig!\n");

    // Read a file
    const read_file = try std.fs.cwd().openFile("output.txt", .{});
    defer read_file.close();
    const content = try read_file.readToEndAlloc(allocator, 1024);
    defer allocator.free(content);
    std.debug.print("Read: {s}", .{content});
}
  std.fs.cwd()        → current working directory
  .createFile(...)    → create or truncate a file
  .openFile(...)      → open existing file
  .makeDir(...)       → create a directory
  .deleteFile(...)    → delete a file
  .readDir(...)       → iterate directory contents

std.ArrayList — Dynamic Array

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const alloc = gpa.allocator();

    var list = std.ArrayList(i32).init(alloc);
    defer list.deinit();

    try list.append(10);
    try list.append(20);
    try list.append(30);
    try list.insert(1, 15);  // insert 15 at index 1

    std.debug.print("List: ", .{});
    for (list.items) |item| std.debug.print("{d} ", .{item});
    std.debug.print("\n", .{});
    // List: 10 15 20 30

    _ = list.orderedRemove(2);  // remove index 2
    std.debug.print("After remove: {d} items\n", .{list.items.len});  // 3
}

std.StringHashMap — Key-Value Store

var map = std.StringHashMap(u32).init(allocator);
defer map.deinit();

try map.put("Alice", 95);
try map.put("Bob",   82);
try map.put("Carol", 91);

if (map.get("Alice")) |score| {
    std.debug.print("Alice: {d}\n", .{score});  // 95
}

// Iterate all entries
var it = map.iterator();
while (it.next()) |entry| {
    std.debug.print("{s}: {d}\n", .{entry.key_ptr.*, entry.value_ptr.*});
}

std.sort — Sorting

const std = @import("std");

pub fn main() void {
    var nums = [_]i32{ 5, 2, 8, 1, 9, 3 };

    std.mem.sort(i32, &nums, {}, std.sort.asc(i32));
    std.debug.print("Ascending:  ", .{});
    for (nums) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
    // Ascending: 1 2 3 5 8 9

    std.mem.sort(i32, &nums, {}, std.sort.desc(i32));
    std.debug.print("Descending: ", .{});
    for (nums) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
    // Descending: 9 8 5 3 2 1
}

std.math — Math Functions

const math = std.math;

std.debug.print("sqrt(16) = {d}\n",   .{math.sqrt(@as(f64, 16.0))});  // 4
std.debug.print("pow(2,10) = {d}\n",  .{math.pow(f64, 2.0, 10.0)});   // 1024
std.debug.print("log2(8)  = {d}\n",   .{math.log2(@as(f64, 8.0))});   // 3
std.debug.print("ceil(2.3) = {d}\n",  .{math.ceil(@as(f64, 2.3))});   // 3
std.debug.print("floor(2.9) = {d}\n", .{math.floor(@as(f64, 2.9))}); // 2
std.debug.print("pi = {d:.5}\n",      .{math.pi});                     // 3.14159

std.time — Timing

const start = std.time.milliTimestamp();

// Do some work...
var sum: u64 = 0;
for (0..1_000_000) |i| sum += i;

const elapsed = std.time.milliTimestamp() - start;
std.debug.print("Sum: {d}, Time: {d}ms\n", .{sum, elapsed});

// Sleep for 500 milliseconds
std.time.sleep(500 * std.time.ns_per_ms);

std.json — JSON Parsing and Writing

const json_text =
    \\{"name":"Zig","version":13,"stable":false}
;

const parsed = try std.json.parseFromSlice(
    struct { name: []const u8, version: u32, stable: bool },
    allocator,
    json_text,
    .{},
);
defer parsed.deinit();

const data = parsed.value;
std.debug.print("{s} v{d} stable={any}\n",
    .{data.name, data.version, data.stable});
// Zig v13 stable=false

std.testing — Unit Test Utilities

test "addition works" {
    try std.testing.expect(2 + 2 == 4);
    try std.testing.expectEqual(@as(i32, 10), add(7, 3));
}

test "string comparison" {
    try std.testing.expectEqualStrings("hello", "hello");
}

test "error handling" {
    try std.testing.expectError(error.DivisionByZero, divide(10, 0));
}

Run all tests with zig test your_file.zig or zig build test in a project. The testing module provides clear failure messages that show the expected and actual values when a test fails.

Leave a Comment

Your email address will not be published. Required fields are marked *