csv_parse.c in C
A complete CSV reader: split lines into fields, trim them, report a summary.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FIELDS 8
static char *trim(char *text) {
while (isspace((unsigned char) *text)) {
text++;
}
char *end = text + strlen(text);
while (end > text && isspace((unsigned char) end[-1])) {
end--;
}
*end = '\0';
return text;
}
static int split(char *line, char sep, char **fields, int max) {
int count = 0;
char *start = line;
for (char *p = line;; p++) {
if (*p == sep || *p == '\0') {
int last = (*p == '\0');
*p = '\0';
if (count < max) {
fields[count++] = trim(start);
}
if (last) {
break;
}
start = p + 1;
}
}
return count;
}
static int is_number(const char *text) {
if (*text == '\0') {
return 0;
}
char *end = NULL;
strtod(text, &end);
return *end == '\0';
}
int main(void) {
char rows[3][64] = {
"lang, tpm, accuracy",
"rust, 104, 97.5",
" sql , 88 , 99.0 ",
};
int numeric = 0;
int textual = 0;
for (int r = 0; r < 3; r++) {
char *fields[MAX_FIELDS];
int n = split(rows[r], ',', fields, MAX_FIELDS);
printf("row %d:", r);
for (int i = 0; i < n; i++) {
printf(" [%s]", fields[i]);
if (r > 0) {
if (is_number(fields[i])) {
numeric++;
} else {
textual++;
}
}
}
printf("\n");
}
printf("%-10s %d\n", "numeric", numeric);
printf("%-10s %d\n", "text", textual);
return 0;
}
How it works
- The parser works on a mutable copy so it can cut in place.
- Each field is trimmed and classified as numeric or text.
- The totals are printed as an aligned table at the end.
Keywords and builtins used here
NULLbreakcharconstelseforifintis_numbermainreturnsplitstatictrimunsignedvoidwhile
The run, in numbers
- Lines
- 80
- Characters to type
- 1267
- Tokens
- 452
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 258 seconds.
Step 1 of 1 in Encore, step 13 of 13 in Strings & text.