C语言读取CSV文件存入数组后所有元素均为最后一行问题求助
问题根因
该问题与fgets特性无关,核心是所有指针复用了同一块内存缓冲区:
- 你定义的
char row[1000]是栈上的固定内存块,运行全程只有唯一的内存地址 - 循环中每次执行
students[i] = row,本质是把数组students的所有元素都指向同一个row的地址 - 每次
fgets调用都会覆盖row的旧内容,循环结束后row仅保留最后一行的数据,因此遍历students数组时所有元素输出的都是最后一行内容
代码冗余点说明
你原有代码中row[strlen(row)] = '\0';逻辑完全冗余:fgets读取内容后会自动在末尾追加\0结束符,该行代码没有实际作用,极端场景下还可能引发越界访问。
修复方案
方案1:动态分配内存存储每行内容
每次读取行后申请独立内存存储内容,避免复用同一块缓冲区:
// 提前引入头文件:#include <stdlib.h> #include <string.h> for(int i = 0; i < rows; i++){ fgets(row,1000,input2); // 可选:去掉fgets读取的换行符 row[strcspn(row, "\n")] = '\0'; // 申请刚好容纳当前行的内存,+1为结束符预留位置 students[i] = malloc(strlen(row) + 1); // 将行内容拷贝到新申请的独立内存中 strcpy(students[i], row); printf("%s", students[i]); }
注意:程序结束不再使用students数组时,需要循环调用free(students[i])释放所有申请的内存,避免内存泄漏
方案2:用二维数组存储所有行
直接给每行分配独立的栈内存,无需手动管理内存:
// 把原有的char *students[rows]替换为二维数组定义 char students[rows][1000]; for(int i = 0; i < rows; i++){ fgets(students[i],1000,input2); students[i][strcspn(students[i], "\n")] = '\0'; printf("%s", students[i]); }
该方案适合确认单行最大长度不超过1000字节的场景,使用更简单无需手动释放内存。
内容的提问来源于stack exchange,提问作者Jairo Flores
相关产品推荐
相关产品推荐

