Dear All,
How to read a csv file in c?
Thank you in advance.
For : quick tokenizers can work for simple, well-formed CSV, but real CSV files often include quoted fields, doubled quotes (""), different separators, and even fields that contain newlines. 's suggestion points you in the simple direction; below is a compact, practical parser you can drop into a C program to handle quoted fields and escaped quotes. It uses a character-state approach rather than strtok/fscanf and is a good starting point for most CSVs. Note: this example strips the newline per line and does not handle fields that span multiple physical lines (those require reading until the closing quote across lines).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **parse_csv_line(char *line, int *out_count) {
int cap = 8, count = 0;
char **fields = malloc(cap * sizeof(char*));
char *p = line;
while (*p) {
char *field = NULL;
if (*p == '"') {
p++; /* quoted field */
char *buf = malloc(64);
int blen = 0, bcap = 64;
while (*p) {
if (*p == '"') {
if (*(p+1) == '"') { /* escaped quote */
if (blen + 1 >= bcap) { bcap *= 2; buf = realloc(buf, bcap); }
buf[blen++] = '"';
p += 2;
} else { p++; break; } /* end quote */
} else {
if (blen + 1 >= bcap) { bcap *= 2; buf = realloc(buf, bcap); }
buf[blen++] = *p++;
}
}
buf[blen] = '\0';
field = buf;
while (*p && *p != ',') p++;
if (*p == ',') p++;
} else {
char *start = p;
while (*p && *p != ',') p++;
int len = p - start;
field = malloc(len + 1);
memcpy(field, start, len);
field[len] = '\0';
if (*p == ',') p++;
}
if (count >= cap) { cap *= 2; fields = realloc(fields, cap * sizeof(char*)); }
fields[count++] = field;
}
*out_count = count;
return fields;
}
int main(void) {
FILE *f = fopen("data.csv", "r");
if (!f) { perror("fopen"); return 1; }
char *line = NULL;
size_t len = 0;
while (getline(&line, &len, f) != -1) {
line[strcspn(line, "\r\n")] = '\0';
int n;
char **flds = parse_csv_line(line, &n);
for (int i = 0; i < n; ++i) { printf("field[%d] = '%s'\n", i, flds[i]); free(flds[i]); }
free(flds);
}
free(line); fclose(f);
return 0;
} Quick notes and troubleshooting
Two ways come to mind:
1) use fscanf(). It naturally breaks with spaces, so if your record fields have just a single word in them, followed by a comma and a space before the next field, it's good. The comma will have to be removed from the last char of the word, however. (easy enough).
2) use strtok(). Set the delimiter to ',' and '\n'. Works on multi word fields, where #1 would not work as easily. Requires the include file string.h be in the header file list.
Post up some code to get started, if you need some help.
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.