如何在C语言中将CSV文件转为二维数组?现有代码无法正常运行
解决C语言读取CSV到二维数组的问题
问题背景
你有如下CSV数据:
S.No, Book Name, Author, Borrowed By, 1, C Programming, Dennis Ritchie, None, 2, C++ Programming, Bjarne Stroustrup, None,
尝试用C语言将其存入二维数组,但编写的代码运行后,最后两行打印输出NULLNULL,无法正确存入数组。你的代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char buffer[1024] ; char *record,*line; int i=0,j=0; char mat[100][100]; FILE *fstream = fopen("Library.csv","r"); if(fstream == NULL) { printf("\n file opening failed "); return -1 ; } while((line=fgets(buffer,sizeof(buffer),fstream))!=NULL) { record = strtok(line,";"); while(record != NULL) { printf("record : %s",record) ; mat[i++][j++] = (record) ; record = strtok(NULL,";"); } ++i ; } printf("%s", mat[1][0]); printf("%s", mat[0][1]); return 0 ; }
问题分析与修复
你的代码存在三个核心错误,逐个修正即可解决问题:
1. 分隔符使用错误
你的CSV文件用**逗号,**作为字段分隔符,但代码里strtok(line,";")用的是分号;,导致无法正确分割字段,record直接拿到整行内容,后续逻辑全部混乱。
2. 二维数组赋值错误
mat是char[100][100]类型的字符数组,用来存储字符串,但你直接写mat[i++][j++] = (record);,这是把字符串指针record的地址强制转换成char存储,完全不是复制字符串的逻辑,正确做法是用strcpy把record的内容复制到mat的对应位置。
3. 索引逻辑混乱
原代码中,每读取一个字段就同时递增i和j,导致字段会被存在mat[0][0]、mat[1][1]、mat[2][2]这种错位的位置,处理完一行后还额外++i,进一步打乱索引。正确的逻辑是:处理一行时,i保持当前行号不变,j从0开始逐个递增;处理完一整行后,i递增到下一行,j重置为0。
修改后的完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char buffer[1024]; char *record, *line; int i = 0, j = 0; char mat[100][100]; // 每个元素存储一个字段字符串 FILE *fstream = fopen("Library.csv", "r"); if (fstream == NULL) { printf("\n file opening failed "); return -1; } while ((line = fgets(buffer, sizeof(buffer), fstream)) != NULL) { // 用逗号和换行符作为分隔符,同时处理末尾的换行和多余的逗号 record = strtok(line, ",\n"); j = 0; // 每处理一行,重置列索引 while (record != NULL) { // 去掉字段前后的空格(可选,根据需求调整) while (*record == ' ') record++; // 复制字符串到二维数组 strcpy(mat[i][j], record); printf("record : %s\n", mat[i][j]); j++; record = strtok(NULL, ",\n"); } i++; // 一行处理完,行索引递增 } // 测试打印:第一行数据的第一个字段(S.No=1)、表头的第二个字段(Book Name) printf("\n%s\n", mat[1][0]); printf("%s\n", mat[0][1]); fclose(fstream); // 记得关闭文件 return 0; }
额外说明
- 代码中加入了去除字段前后空格的逻辑,因为你的CSV里每个字段前有空格(比如
, Book Name),如果不需要可以去掉这部分。 - 增加了
fclose(fstream),避免文件资源泄漏。 - 用
,\n作为strtok的分隔符,同时处理字段间的逗号和行尾的换行符,避免把换行符也存入数组。
内容的提问来源于stack exchange,提问作者Dhayananth J
相关产品推荐
相关产品推荐

