C语言使用strtok函数拆分CSV内容存入数组后输出异常
问题根因
- 你的
name数组存储的是strtok返回的指针,这些指针全部指向栈上的同一个buffer数组内存空间。每次调用fgets读取新行时,buffer的内容会被新读取的行数据覆盖,之前存入name数组的指针指向的内容也会随之被修改,最终所有指针指向的buffer里存的都是最后一行的内容,所以遍历输出时全是最后一个元素。 - 额外问题:你声明的
int count没有初始化就用在循环终止条件里,属于未定义行为;char *name[20]只有20个元素的存储容量,你的代码里i已经增长到21,出现数组越界,会触发内存访问异常。
修复方案
- 每次拆分出字符串后,单独分配内存存储内容,不要直接保存指向
buffer的指针 - 给
count变量赋值为实际读取到的元素数量i,避免未初始化问题 - 限制存储的元素数量不超过
name数组的容量,避免越界
修复后代码
#include <stdio.h> #include <string.h> #include <stdlib.h> // 新增头文件,用于内存分配 int i = 0; int j = 0; #define NAME_MAX_CNT 20 // 定义数组最大容量 char *name[NAME_MAX_CNT]; int main() { FILE *fp = fopen("meetingData.csv", "r"); if (!fp) { printf("Can't open file\n"); return 1; } char buffer[1024]; while (fgets(buffer, 1024, fp) && i < NAME_MAX_CNT) { // 增加越界判断 char *value = strtok(buffer, ", "); int x = 0; while (value != NULL) { if (x == 0) { name[i] = strdup(value); // 分配独立内存存储字符串 printf("name[%d]is %s\n", i, name[i]); i++; x++; } else if (x == 1) { x++; } else { x++; j++; } value = strtok(NULL, ","); } } int count = i; // 用实际读取的数量赋值count for (int k = 0; k < count; k++) { printf("%s\n", name[k]); free(name[k]); // 用完释放分配的内存,避免内存泄漏 } fclose(fp); return 0; }
补充说明
如果你的编译环境不支持strdup,可以替换为手动分配内存的写法:
name[i] = malloc(strlen(value) + 1); strcpy(name[i], value);
注意要给字符串末尾的\0多分配1字节空间。
内容的提问来源于stack exchange,提问作者Rasathurai Karan
相关产品推荐
相关产品推荐

