Libcsv库解析csv格式文件
一、问题引入#
数据通信和数据存储的格式是多种多样的,不同的人会选择不同的数据格式,这就涉及数据格式的转换。
csv
格式的文件在数据通信和存储使用较多,有必要记录一下csv
格式文件的读写。
二、解决过程#
编写程序的一个重要原则:切记不要重复造轮子。 查询到处理csv格式文件的开源库:libcsv
关于libcsv的详细说明,请自行参考开源地址中 csv.pdf
解析csv格式文件
💡 文件若是utf-8编码且含有中文,控制台显示汉字乱码(原因:控制台显示字符编码是ansi);建议文件以ansi编码形式
#include <string.h>
#include "csv.h"
struct Student
{
int id;
int age;
char sex[10];
char name[10];
};
struct DataHandle
{
int col;
int row;
struct Student stu;
};
// 列级数据处理回调函数(先处理)
void col_callback(void *s, size_t len, void *data)
{
struct DataHandle *handle = (struct DataHandle *)data;
char *str = malloc(len + 1);
memset(str, 0, len + 1);
memcpy(str, (char *)s, len);
switch (handle->col) // 列值匹配,注意行和列都是从0开始
{
case 0:
handle->stu.id = atoi(str);
break;
case 1:
memcpy(handle->stu.name, str, len + 1);
break;
case 2:
memcpy(handle->stu.sex, str, len + 1);
break;
case 3:
handle->stu.age = atoi(str);
default:
break;
}
free(str);
// 列计数 + 1
(handle->col)++;
}
// 行级数据处理回调函数(后处理)
void row_callback(int c, void *data)
{
printf("%d\n", c); // 行结束符的ASCII值
struct DataHandle *handle = (struct DataHandle *)data;
printf("{id:%d, name:\"%s\", sex:\"%s\", age:%d}\n",
handle->stu.id, handle->stu.name, handle->stu.sex, handle->stu.age);
// 行计数 + 1,列计数 清零
(handle->row)++;
printf("row:%d col:%d\n", handle->row, handle->col);
handle->col = 0;
}
int csv_parse_file(const char *file_path, void(*cols_callback)(void *, size_t, void *),
void(*rows_callback)(int c, void *), void *data)
{
struct csv_parser conf;
FILE *fp = NULL;
size_t bytes_read = 0;
size_t retval = 0;
char buf[1024] = { 0 };
int result = -1;
if (csv_init(&conf, CSV_STRICT | CSV_STRICT_FINI) != 0) // 初始化
{
printf("failed to initialize csv parser\n");
return result;
}
fp = fopen(file_path, "rb"); // 打开文件(二进制只读模式)
if (fp == NULL)
{
fprintf(stderr, "Failed to open file %s: %s\n", file_path, strerror(errno));
goto END;
}
while ((bytes_read = fread(buf, sizeof(char), sizeof(buf), fp)) > 0)
{
retval = csv_parse(&conf, buf, bytes_read, cols_callback, rows_callback, data);
if (retval != bytes_read)
{
fprintf(stderr, "Error parsing file: %s\n", csv_strerror(csv_error(&conf)));
goto END;
}
}
if (0 != csv_fini(&conf, cols_callback, rows_callback, data))
{
goto END;
}
result = 0;
END:
csv_free(&conf);
fclose(fp);
return result;
}
int main(int argc, const char *argv[])
{
const char *file_path = { "student_data.csv" };
struct DataHandle handle = { 0 };
csv_parse_file(file_path, col_callback, row_callback, &handle);
return 0;
}
三、反思总结#
libcsv解析流程:
- csv_init() 初始化
- fread() 读取数据
- csv_parse() 解析数据
- csv_fini() 处理最后的数据
- csv_free() 释放内存
四、参考引用#
无
作者:caojun97
出处:https://www.cnblogs.com/caojun97/p/17219273.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!