A program usually has three standard streams:
standard input
standard output
standard errorStandard input is where the program reads ordinary input. Standard output is where it writes ordinary output. Standard error is where it writes diagnostics.
In Zig:
const stdin = std.io.getStdIn();
const stdout = std.io.getStdOut();
const stderr = std.io.getStdErr();These values are file-like handles.
A small program can read from standard input and write to standard output:
const std = @import("std");
pub fn main() !void {
const stdin = std.io.getStdIn();
const stdout = std.io.getStdOut();
var buffer: [1024]u8 = undefined;
while (true) {
const n = try stdin.read(&buffer);
if (n == 0)
break;
try stdout.writeAll(buffer[0..n]);
}
}This is a copy program. It reads bytes until end-of-file and writes the same bytes back.
Run it like this:
zig run main.zigType some text, then send end-of-file. On Unix systems this is usually Ctrl-D. On Windows it is usually Ctrl-Z followed by Enter.
The same program can read from a file by shell redirection:
zig run main.zig < input.txtIt can write to a file:
zig run main.zig > output.txtIt can do both:
zig run main.zig < input.txt > output.txtNo Zig code changed. The shell connected the streams.
Standard error is separate from standard output. This matters because diagnostics should not mix with program output.
const std = @import("std");
pub fn main() !void {
const stderr = std.io.getStdErr();
try stderr.writeAll("error: missing input\n");
}With this separation, a program can write normal output to one place and errors to another:
zig run main.zig > output.txt 2> error.txtFor formatted output, use a writer:
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut();
try stdout.writer().print(
"answer = {d}\n",
.{42},
);
}writeAll writes bytes. print formats values first.
For diagnostics, std.debug.print is common during development:
std.debug.print("x = {d}\n", .{x});It writes to standard error.
This is useful because debug messages should not corrupt standard output, especially when output is piped into another program.
A filter program follows a simple rule:
read from standard input
write results to standard output
write diagnostics to standard errorThat rule makes programs easy to connect.
Exercise 13-17. Write a program that copies standard input to standard output.
Exercise 13-18. Change the program so it counts bytes and prints the count to standard error.
Exercise 13-19. Write a program that converts lowercase ASCII letters from standard input to uppercase.
Exercise 13-20. Write a program that prints usage information to standard error when given no arguments.