i have 2 questions in this code…
how do i get rid of the else in parsing var1?
how can i coerse the var2 and var3 to a slice?
this just parses command line, var1 needs to be integer, var2 and var3 needs to be slices…
but no matter what i do, it just doesn’t work…
pub fn ParseCmdLine(allocator: std.mem.Allocator) !struct { u16, []const u8, []const u8 } {
var var1: u16 = 3260;
var var2: [32]u8 = undefined;
var var3: [32]u8 = undefined;
var args = try std.process.ArgIterator.initWithAllocator(allocator);
defer args.deinit();
_ = args.skip();
while (args.next()) |arg| {
if (std.fmt.parseInt(u16, arg, 10)) |p| {
var1 = p;
} else |err| {
switch (err) {
error.InvalidCharacter => {
//continue;
},
else => {
//continue;
},
}
}
if (arg[1] == 58) {
for (arg, 0..arg.len) |v, i| {
var2[i] = v;
}
continue;
}
if (std.mem.eql(u8, arg[arg.len-4..], ".cfg")) {
for (arg, 0..arg.len) |v, i| {
var3[i] = v;
}
continue;
}
}
return .{ var1, &var2, &var3 };
}
vulpesx
November 28, 2025, 6:32am
2
you can catch errors
var1 = std.fmt.parseInt(u16, arg, 10) catch |err| switch (err) {…};
you can also see that you can remove a level of indentation if the block only has 1 statement/expression.
var2/3 can be coerced to slices with just &, or [start..end]
You have a bigger issue, you are returning pointers to var2/3 which are on the stack of the function. After the function returns these pointers are invalid, and the data they point to can be overwritten.
You should instead take buffer(s) (you could use a single backing buffer for both) for var2/3 as parameters and return sub slices of that.
1 Like
i’ve made it like this but now its returning error: expected type ‘u16’, found ‘void’
error.InvalidCharacter => {
I really don’t want to handle the error…(just return 0 might be fine…)
var1 = std.fmt.parseInt(u16, arg, 10) catch |err|
switch (err) {
error.InvalidCharacter => {
//continue;
},
else => {
//continue;
},
};
as for var2/var3, can you give an example of backing buffer you have told me…i’m sorry, i’m just a newbie…is it a vector or an arraylist?
vulpesx
November 28, 2025, 7:46am
4
i’ve made it like this but now its returning error: expected type ‘u16’, found ‘void’
error.InvalidCharacter => {
you have to either result in a u16 or coercible to u16 value, return from the function, break or continue the loop.
you can just error.InvalidCharacter => 0,
if you want to procede without assigning to var1, then you have to stick with if else
just a slice
pub fn ParseCmdLine(allocator: std.mem.Allocator, args_buf: []const u8)
But since you are taking an allocator already, you could allocate them.
which you would do with an arraylist, vector is a math concept that is a terrible name for this, blame cpp. Vectors in zig are for simd math.
pub fn parseCmdLine(allocator: std.mem.Allocator) !struct { u16, []const u8, []const u8 } {
var var1: u16 = 3260;
var var2: std.ArrayList(u8) = .empty;
errdefer var2.deinit(allocator);
var var3: std.ArrayList(u8) = .empty;
errdefer var3.deinit(allocator);
var args = try std.process.ArgIterator.initWithAllocator(allocator);
defer args.deinit();
_ = args.skip();
while (args.next()) |arg| {
parse_var1: {
var1 = std.fmt.parseInt(u16, arg, 10) catch break :parse_var1;
continue;
}
parse_var2: {
if (arg[1] != 58) break :parse_var2;
var2.clearRetainingCapacity();
try var2.appendSlice(allocator, arg);
continue;
}
parse_var3: {
if (!std.mem.endsWith(u8, arg, ".cfg")) break :parse_var3;
var3.clearRetainingCapacity();
try var3.appendSlice(allocator, arg);
continue;
}
}
return .{ var1, try var2.toOwnedSlice(allocator), try var3.toOwnedSlice(allocator) };
}