Text I/O

Let’s take a look at reading and writing text. The examples here all use buffered I/O, so we’ll have to supply a buffer and (when writing) flush it at the end.

Writing to standard out

First: writing to standard out.

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    // Get a File for standard out, then create a
    // File.Writer and get its Io.Writer.
    var buf: [4096]u8 = undefined;
    var writer = std.Io.File.stdout().writerStreaming(
        io,
        &buf,
    );
    var stdout = &writer.interface;

    try stdout.writeAll("Hello, world!\n");
    try stdout.print("A number: {d:.2}\n", .{3.14159});

    // Don’t forget to flush!
    try writer.flush();
}
$ zig run text.zig 
Hello, world!
A number: 3.14

Reading from standard in

The next example reads text from standard input and prints it with line numbers.

const std = @import("std");
const print = std.debug.print;

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    // Get a File for standard input, then create a
    // File.Reader and get its Io.Reader.
    var buf: [4096]u8 = undefined;
    var reader = std.Io.File.stdin().readerStreaming(
        io,
        &buf,
    );
    var stdin = &reader.interface;

    // Read input one line at a time.
    var n: u64 = 0;
    while (try stdin.takeDelimiter('\n')) |line| {
        n += 1;
        print("{d} {s}\n", .{ n, line });
    }
}
$ echo cat > animals
$ echo dog >> animals
$ echo earthworm >> animals
$ zig run text-2.zig < animals 
1 cat
2 dog
3 earthworm

Writing to a file

Next up: writing to a file:

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    // Get the current working directory, then
    // create & open the file.
    const cwd = std.Io.Dir.cwd();
    var file = try cwd.createFile(io, "hello", .{});
    var buf: [4096]u8 = undefined;
    var writer = file.writerStreaming(io, &buf);
    var w = &writer.interface;

    try w.writeAll("Hello, world!\n");
    try w.print("A number: {d:.2}\n", .{3.14159});

    try writer.flush();
}
$ zig run text-3.zig 
$ cat hello
Hello, world!
A number: 3.14

Reading from a file

The last example prints a file with line numbers:

const std = @import("std");
const print = std.debug.print;

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    const cwd = std.Io.Dir.cwd();
    var file = try cwd.openFile(io, "animals", .{});
    var buf: [4096]u8 = undefined;
    var reader = file.readerStreaming(io, &buf);
    var r = &reader.interface;

    var n: u64 = 0;
    while (try r.takeDelimiter('\n')) |line| {
        n += 1;
        print("{d} {s}\n", .{ n, line });
    }
}
$ echo cat > animals
$ echo dog >> animals
$ echo echidna >> animals
$ zig run text-4.zig 
1 cat
2 dog
3 echidna

Next example: Binary I/O.