1、使用 fgets + strtok 解析 CSV
fopen 打开 CSV 文件。fgets 逐行读取文件内容。strtok 分割每一行的字段(使用 , 作为分隔符)。atoi / atof 将字符串转换为整数或浮点数(如果需要)。fclose 关闭文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 1024  // 每行最大长度
#define MAX_FIELD 50   // 每个字段的最大长度
int main() {
    FILE *file = fopen("data.csv", "r");  // 读取 CSV 文件
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }
    char line[MAX_LINE];  // 存储读取的行
    // 读取表头(第一行)
    if (fgets(line, sizeof(line), file)) {
        printf("Header: %s\n", line);
    }
    // 逐行读取文件内容
    while (fgets(line, sizeof(line), file)) {
        char *token;
        int id;
        char name[MAX_FIELD];
        int age;
        // 解析第一列(ID)
        token = strtok(line, ",");
        if (token != NULL)
            id = atoi(token);
        // 解析第二列(Name)
        token = strtok(NULL, ",");
        if (token != NULL)
            strncpy(name, token, MAX_FIELD);
        // 解析第三列(Age)
        token = strtok(NULL, ",");
        if (token != NULL)
            age = atoi(token);
        printf("ID: %d, Name: %s, Age: %d\n", id, name, age);
    }
    fclose(file);
    return 0;
}
2、使用 sscanf 解析 CSV
使用 sscanf 解析固定格式的 CSV。
#include <stdio.h>
#include <stdlib.h>
int main() {
    FILE *file = fopen("data.csv", "r");
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }
    char line[1024];
    int id, age;
    char name[50];
    // 读取表头(跳过)
    fgets(line, sizeof(line), file);
    // 逐行读取
    while (fgets(line, sizeof(line), file)) {
        if (sscanf(line, "%d,%49[^,],%d", &id, name, &age) == 3) {
            printf("ID: %d, Name: %s, Age: %d\n", id, name, age);
        }
    }
    fclose(file);
    return 0;
}
3、处理带引号的 CSV
CSV 文件中字段被引号包围(如 "Alice, Smith"),strtok 和 sscanf 可能会解析错误。要正确解析带引号的字段,需要手动处理引号。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse_csv_line(char *line) {
    char *ptr = line;
    char field[256];
    int inside_quotes = 0;
    while (*ptr) {
        if (*ptr == '"') {
            inside_quotes = !inside_quotes;  // 切换引号状态
        } else if (*ptr == ',' && !inside_quotes) {
            printf(" | ");  // 分隔字段
        } else {
            printf("%c", *ptr);
        }
        ptr++;
    }
    printf("\n");
}
int main() {
    FILE *file = fopen("data.csv", "r");
    if (!file) {
        perror("无法打开文件");
        return 1;
    }
    char line[1024];
    // 读取表头(跳过)
    fgets(line, sizeof(line), file);
    // 读取数据行
    while (fgets(line, sizeof(line), file)) {
        parse_csv_line(line);
    }
    fclose(file);
    return 0;
}
4、 处理大 CSV 文件
如果 CSV 文件很大,可以使用逐行读取 + 动态存储。使用 getline 代替 fgets 处理任意长度的行。
#include <stdio.h>
#include <stdlib.h>
void process_csv_large_file(const char *filename) {
    FILE *file = fopen(filename, "r");
    if (!file) {
        perror("文件打开失败");
        return;
    }
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, file)) != -1) {
        printf("%s", line);  // 这里可以做更复杂的数据处理
    }
    free(line);
    fclose(file);
}
int main() {
    process_csv_large_file("data.csv");
    return 0;
}