Zig Parsing Numbers
Parsing turns text into a number. std.fmt.parseInt reads digits in a base and returns either the number or an error.
try reads a number out of text
parseInt converts each string to an i32. The try keyword sends any parse error to the caller of main.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const count = try std.fmt.parseInt(i32, "42", 10);
const drop = try std.fmt.parseInt(i32, "-17", 10);
try out.print("{d}\n", .{count});
try out.print("{d}\n", .{drop});
}catch swaps a bad parse for a fallback
A good string parses as usual and the fallback is ignored. A bad string fails, so catch supplies the fallback value instead.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const good = std.fmt.parseInt(i32, "7", 10) catch 0;
const bad = std.fmt.parseInt(i32, "abc", 10) catch 0;
const mixed = std.fmt.parseInt(i32, "12x", 10) catch -1;
try out.print("{d}\n", .{good});
try out.print("{d}\n", .{bad});
try out.print("{d}\n", .{mixed});
}allocPrint builds a string to keep
allocPrint formats values into a new string in memory. A defer frees that string when the scope ends.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const alloc = std.heap.page_allocator;
const text = try std.fmt.allocPrint(alloc, "{s}-{d}", .{ "item", 42 });
defer alloc.free(text);
try out.print("{s}\n", .{text});
try out.print("{d}\n", .{text.len});
}Example
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const alloc = std.heap.page_allocator;
const first = try std.fmt.parseInt(i32, "120", 10);
const second = try std.fmt.parseInt(i32, "22", 10);
const spare = std.fmt.parseInt(i32, "oops", 10) catch 0;
const text = try std.fmt.allocPrint(alloc, "total: {d}", .{first + second + spare});
defer alloc.free(text);
try out.print("{s}\n", .{text});
try out.print("{d}\n", .{text.len});
}Key points
- parseInt: std.fmt.parseInt(T, text, base) converts text to a value of type T.
- Base: the last argument is the number base, and 10 means decimal.
- Error union: parseInt returns a value or an error, so a call needs try or catch.
- try: try passes a parse error up to the caller.
- catch: catch swaps a parse error for a fallback value.
- allocPrint: std.fmt.allocPrint builds a formatted string in memory the caller must free.
In this example, try parses 120 and 22 from text into i32 values. The word oops cannot parse, so catch gives the fallback 0 for spare. allocPrint then builds the label total: 142 from the sum, a defer frees it, and its length prints as 10.
Note
text that is not a valid number, such as abc, fails with an InvalidCharacter error.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What happens when parseInt reads the text abc as an i32 in base 10?