C语言中,没有内置的 CSV 解析库,因此需要使用 fopen、fgets 和 strtok(或其他方法)来手动解析 CSV 文件。从 CSV 文件中读取的字段都是字符串,如果需要将其转换为其他数据类型(如整数、浮点数),可以使用 atoi、atof 等函数。一些csv文件会用引号将字符串包裹起来。如果遇到这种情况,需要添加代码去除引号。若csv文件过大,需要注意内存的使用,防止内存溢出。

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"),strtoksscanf 可能会解析错误。要正确解析带引号的字段,需要手动处理引号。

#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;
}

推荐文档

相关文档

大家感兴趣的内容

随机列表