Split the line by delimiter to get spesific column in csv file

Currently i’m learning zig for personal purpose. I treid to process the large csv file to get one column and printed out spesific value on that column .

Here’s the part of the code

while (true) {
        reader.streamUntilDelimiter(arr.writer(), '\n', null) catch |err| switch (err) {
            error.EndOfStream => break,
            else => return err,
        };

        // getting line to read
        const line = arr.items;

        // std.debug.print("{s}", .{line});

        // Split the line by delimiter (e.g., comma, tab, space) to get columns
       const columns = std.mem.split(u8, line, ',');

        // Filter specific column (e.g., column index 1)
        const specificColumnIndex = 1; 
        if (specificColumnIndex < columns.len) {
            const specificColumn = columns[specificColumnIndex];
            std.debug.print("{s}\n", .{specificColumn}); // Print the specific column
        }

        arr.clearAndFree();
    }

getting error "

src/main.zig:35:49: error: expected type '[]const u8', found 'comptime_int'
        const columns = std.mem.split(u8, line, ',');

"

I dont know how to address this error

I believe it may be expecting a []const u8 and you are simply providing a u8.

i.e. it wants "," and not ','.

I’m also seeing that the split function is marked as depreciated and that you should use splitAny.

This will compile.

const std = @import("std");

pub fn main() !void {
    var file = try std.fs.cwd().openFile("foo.txt", .{});
    defer file.close();

    var buf_reader = std.io.bufferedReader(file.reader());
    var in_stream = buf_reader.reader();

    var buf: [1024]u8 = undefined;
    while (try in_stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
        // std.debug.print("{s}", .{line});

        // Split the line by delimiter (e.g., comma, tab, space) to get columns
        var it = std.mem.splitAny(u8, line, ",");
        const first_slice = it.first();
        std.debug.print("{s}, ", .{first_slice});
        while (it.next()) |item| {
            std.debug.print("{s}, ", .{item});
        }
    }
}

input

1,2,3
a,b,c

output

1, 2, 3, a, b, c, 

Would be better to use splitScalar since it’s only one character:

std.mem.splitScalar(u8, line, ',');

splitScalar is faster than splitAny/splitSequence, so it should be used whenever possible.

Got it. Thank you @Judsen @squeek502

1 Like