# Standard Input and Output

### Standard Input and Output

A program usually has three standard streams:

```text
standard input
standard output
standard error
```

Standard 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:

```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:

```zig
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:

```sh
zig run main.zig
```

Type 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:

```sh
zig run main.zig < input.txt
```

It can write to a file:

```sh
zig run main.zig > output.txt
```

It can do both:

```sh
zig run main.zig < input.txt > output.txt
```

No 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.

```zig
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:

```sh
zig run main.zig > output.txt 2> error.txt
```

For formatted output, use a writer:

```zig
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:

```zig
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:

```text
read from standard input
write results to standard output
write diagnostics to standard error
```

That 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.

