C语言如何实现类Excel表格数据写入文件及按名称查询功能
实现方案思路
1. 存储格式选择
优先选CSV格式作为存储方案,完全匹配你需要的表格结构,无需依赖第三方库,读写逻辑简单,内存开销远低于cJSON,没有多余的结构字段占用。你给出的样例表格存成CSV格式如下:
name,value name1,22 name2,23 name2,"33, 22, 34"
如果B列存在逗号分隔的多值,用双引号把整段值包裹即可,解析逻辑可以兼容这种情况。如果有更高的性能要求,也可以自定义简单二进制格式:每条记录依次存「名称长度、名称字符串、值长度、值内容」,读写速度更快,内存占用更低,缺点是可读性不如文本格式。
2. 查询功能实现逻辑
根据数据量选择对应的实现方案即可:
- 数据量小于1万条:每次查询直接逐行读取文件解析,匹配A列名称,匹配到就返回对应B列值,查询结束释放所有临时内存,全程内存占用极低。
- 数据量大于1万条:首次读取文件时构建哈希索引,存储A列名称和对应记录在文件中的偏移量,后续查询直接跳转到偏移量读取对应行即可,无需每次遍历全量文件,查询效率更高。
3. 最简实现代码示例
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_NAME_LEN 64 #define MAX_VALUE_LEN 256 /** * 按名称查询对应值 * @param target_name 要查询的名称 * @param csv_path 存储数据的CSV文件路径 * @param out_value 存储查询结果的缓冲区 * @return 0查询成功,-1未找到对应名称,-2文件读取错误 */ int query_value_by_name(const char* target_name, const char* csv_path, char* out_value) { FILE* fp = fopen(csv_path, "r"); if (!fp) return -2; char line[MAX_NAME_LEN + MAX_VALUE_LEN + 2]; // 跳过表头行 fgets(line, sizeof(line), fp); while (fgets(line, sizeof(line), fp)) { char name[MAX_NAME_LEN] = {0}; char* comma_pos = strchr(line, ','); if (!comma_pos) continue; // 切分A列名称 int name_len = comma_pos - line; if (name_len >= MAX_NAME_LEN) continue; strncpy(name, line, name_len); name[name_len] = '\0'; // 匹配目标名称 if (strcmp(name, target_name) == 0) { char* value_start = comma_pos + 1; // 去掉末尾换行符 char* newline_pos = strchr(value_start, '\n'); if (newline_pos) *newline_pos = '\0'; // 处理带双引号的多值情况 if (value_start[0] == '"') { value_start++; char* end_quote = strchr(value_start, '"'); if (end_quote) *end_quote = '\0'; } strcpy(out_value, value_start); fclose(fp); return 0; } } fclose(fp); return -1; } // 测试用例 int main() { char result[MAX_VALUE_LEN]; int ret = query_value_by_name("name2", "./data.csv", result); if (ret == 0) { printf("查询结果:%s\n", result); } else if (ret == -1) { printf("错误:未找到对应名称\n"); } else { printf("错误:文件读取失败\n"); } return 0; }
4. 可优化方向
- 如果一个名称对应多条B列值,匹配到结果时不要立刻返回,把所有匹配值存入输出数组即可。
- 频繁修改数据的场景可以加一层内存缓存,批量修改完成后统一写回文件,减少IO操作开销。
- 对性能要求极高的场景可以改用定长二进制存储,查询时可以直接用二分查找,速度远快于逐行遍历。
内容的提问来源于stack exchange,提问作者horsemann07
相关产品推荐
相关产品推荐

