data-structures · intermediate · ~25 min
In-place tokenization without allocation; pointer-into-buffer arithmetic.
Split one CSV row into its comma-separated fields, in place.
Implement int csv_parse_row(char *row, char **fields, int max_fields). Split row on commas in place — overwrite each , with '\0' — and store a pointer to the start of each field in fields[]. Return the number of fields found. There is no quoting; commas always separate fields.
Strip a trailing '\n' (or '\r\n') from row before splitting. Stop adding fields once max_fields pointers have been stored.
row: a writable, NUL-terminated buffer holding one CSV row (may end in a newline).fields: an array of at least max_fields char * slots to fill.max_fields: the maximum number of field pointers to store.int: the number of fields written into fields. Each fields[i] points into row. Non-empty input always yields at least 1 field.
"a,b,c" -> 3 fields: "a", "b", "c"
"single" -> 1 field: "single"
"a,,b\n" -> 3 fields: "a", "", "b" (newline stripped)
"trailing," -> 2 fields: "trailing", "" (empty trailing field)
row. fields[i] must point into the row buffer.CSV is the eternal interchange format. A simple, non-quoting parser is enough for >80% of real CSV files and is a great exercise in stateless splitting.
row: writable NUL-terminated buffer (may end in newline); fields: array of >= max_fields char *; max_fields: pointer-slot count.
int: number of fields; each fields[i] points into row.
No malloc. Modifies row in place.
int csv_parse_row(char *row, char **fields, int max_fields) { /* TODO */ return 0; }
Allocating strdup'd copies (the API contract says split in place); not stripping trailing newline; off-by-one in max_fields.
Empty row returns 1 with fields[0] = empty string. Trailing comma yields an empty last field.
O(row length).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.