Dear All,

How to read a csv file in c?
Thank you in advance.

Dani AI

Generated

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

  • Free every allocated field and the returned array to avoid leaks.
  • Strip UTF-8 BOM on the very first line if present.
  • For CSVs where fields may contain real newlines, read records with a stateful loop that appends lines until a closing quote is found.
  • Dialects vary: semicolon separators, different quote rules, and encodings exist — test with representative samples like:
    • a,b,c
    • "text, with comma",x
    • "escaped ""quote""",end
  • If you need full RFC-compliance or higher performance, prefer a battle-tested C CSV library (for example libcsv) rather than rolling a complex parser yourself.

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.