Character Representation
Every character you see on your computer has a corresponding numeric code. This code is part of a standard called ASCII (American Standard Code for Information Interchange), where each letter, number, and symbol is represented by an unsigned integer value.
The {c} format, which prints a u8 as an ASCII character, is very useful. Here’s a summary of the most commonly used ASCII codes:
Alphanumeric ASCII Character Codes
|
48-57 |
Numeric digits |
0 1 2 3 4 5 6 7 8 9 |
|
65-90 |
Uppercase letters of the alphabet |
A B C ... X Y Z |
|
97-122 |
Lowercase letters of the alphabet |
a b c ... x y z |
In the following example, we’ve chosen the character 'a' to print it in its different numeric representations. As you already know, numbers can be represented in different bases (binary, decimal, hexadecimal, etc.).
print_char.zig |
|
const std = @import("std"); const print = std.debug.print; pub fn main() void { const c_a = 'a'; print("\nCharacter '{c}':", .{c_a}); print("\n_______________________________", .{}); print("\ndecimal:\t\t{d}", .{c_a}); print("\nhexadecimal:\t{x}", .{c_a}); print("\nbinary:\t\t{b}\n", .{c_a}); } |
|
$ zig run print_char.zig |
|
Character 'a': _______________________________ decimal: 97 hexadecimal: 61 binary: 1100001 |
One thing to keep in mind is that this only works correctly with ASCII values between 0 and 127, which correspond to the standard ASCII set. Starting from value 128, the codes represent “extended” or Unicode characters. A good example is the spanish letter Ñ. If you change the value of c_a and run the program again, you can see it for yourself:
|
const c_a = 'Ñ'; |
|
$ zig run print_char.zig |
|
Character '�': _______________________________ decimal: 209 hexadecimal: d1 binary: 11010001 |
Fortunately, even though {c} is limited to standard ASCII, Zig works internally with UTF-8, which does include characters like Ñ. So to print that character correctly, we’ll need to use a small trick… which we’ll see a bit later.
Function Aliases
We’ve also made a small change to avoid typing too much. We declared a constant pointing to the print function from Zig’s standard library:
|
const print = std.debug.print; |
This way, we have an alias for print. Instead of writing every time:
|
std.debug.print("...", .{}); |
We can simply write:
|
print("...", .{}); |
Take note of this. It’ll save you from repeating long paths. This technique can be used for functions, modules, and more.
Escape Sequences
In the print_char.zig example, besides \n (newline), which we’ve seen before, we now also use \t. Back in the first “Hello, world” example, I promised we’d cover this in detail. These are technically called escape characters, or more precisely, escape sequences. I think “sequences” is more accurate, since we’re not inserting just a single character.
|
\n |
Newline |
|
\r |
Carriage return: moves the cursor to the start of the line (without a line break) |
|
\t |
Tab |
|
\\ |
Backslash - lets you print a backslash |
|
\' |
Single quote |
|
\" |
Double quote |
|
\xNN |
8-bit hexadecimal byte (2 digits) |
|
\u{NNNNNN} |
Hexadecimal Unicode code point (encoded as UTF-8, 1 or more digits) |
These sequences are useful for inserting special characters that can’t be typed directly from the keyboard.