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.
row is mutable CSV string; fields receives token pointers up to max_fields.
int csv_parse_row(char *row, char **fields, int max_fields) { /* TODO */ return 0; }
Writing past max_fields in fields array.
Empty row, row with trailing newline, row with more columns than max_fields.
O(row length).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.