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