I am using the following code snippet to try to read an input text file from advent of code, doing a line by line read. for this I am using the function: takeDelimiterExclusive.
The problem: it seems only the first line is being printed, the seek position stays before the delimiter character meaning each subsequent function call will too do the same and returns an empty string.
The question: am I using this function wrong ? should i use takeDelimiterInclusive (which works) ? or is there another preferred method to achieve what i am trying to do ? Thanks in advance
// I am using Zig version 0.16.0-dev.2223+4f16e80ce
const std = @import("std");
pub fn main(init: std.process.Init) !void {
const io = init.io;
const absolute_path = "/home/user/Desktop/Projects/AdventOfCode/2025/01/input.txt";
const file = try std.Io.Dir.openFileAbsolute(io, absolute_path, .{});
defer file.close(io);
var buffer: [4096]u8 = undefined;
var reader = file.reader(io, &buffer);
while (true) {
const line = reader.interface.takeDelimiterExclusive('\n') catch |e| {
if (e == error.EndOfStream) break;
return e;
};
std.debug.print("{s}\n", .{line});
}
}
As the name suggests, it doesnât take (consume) the delimiter. So, to make your code work, you need to consume the delimiter to make progress. Since you know that the delimiter is 1 byte, you can call take(1)toss(1) after you take the line.
It isnât globally the best. But it does what most people want when looking for a function like this: in \n terms, it gives you a line, then it gives you another line, and when there are none left it returns null.
For the other 10% of cases, thereâs the other two.
ah right - takeDelimiter consumes the delimiter but doesnât include it in the return slice. I donât love the name, but Iâm sure thereâs reasoning why it isnât âtakeDelimitedâ.
Also handles end of stream that doesnât end with the delimiter, so really is the idiomatic âread by linesâ. In other bloaty languages, youâd have a âread_lineâ that assumes â\nâ delimited.
Youâre completely right. My suggestion of .toss comes from me being too stuck dealing with network protocols recently where I want to distinguish between EOF and a delimiter (CRLF usually).