C语言读取txt文件解析内容存入数组出现元素被覆盖问题求助
问题原因
你的elements是字符指针数组,所有元素存储的都是同一个item缓冲区的内存地址。每次循环调用sscanf都会覆盖item里的内容,循环结束后item中存储的是最后一行解析到的KitKat,所以不管访问elements的哪个下标,最终读取的都是同一块内存的内容,自然输出都是一样的。
除此之外你的代码还有两个可优化点:
sscanf的%[a-zA-Z]对应的参数item本身就是数组首地址,不需要加取地址符&- 直接把字符串作为
printf第一个参数存在格式化字符串注入风险,建议改成printf("%s", elements[下标])的写法
解决方案
你可以选择两种常用方案修复:
方案1:使用strdup复制字符串到独立堆空间
strdup会自动申请足够的堆内存存储传入的字符串内容,返回新内存的首地址,保证每个elements元素指向的内存空间独立:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char line[100]; char *elements[100] = {NULL}; int i_stock[100]; int r2 = 0; char item[20] = {0}; int stock; FILE *the_file = fopen("inventory.txt","r"); if(the_file == NULL) { perror("Inventarfehler"); exit(1); } while(fgets(line, sizeof(line), the_file)) { sscanf(line, "%[a-zA-Z];%d", item, &stock); // 复制字符串到新的堆内存 elements[r2] = strdup(item); i_stock[r2] = stock; r2++; } printf("%s", elements[2]); // 程序退出前释放申请的堆内存,避免泄漏 for (int i = 0; i < r2; i++) { free(elements[i]); } fclose(the_file); return 0; }
方案2:把elements改成二维字符数组
直接在栈上预分配足够的存储空间,每次循环把解析到的字符串拷贝到对应下标的数组空间里:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char line[100]; // 改成二维数组,每个元素是长度20的字符数组 char elements[100][20] = {0}; int i_stock[100]; int r2 = 0; char item[20] = {0}; int stock; FILE *the_file = fopen("inventory.txt","r"); if(the_file == NULL) { perror("Inventarfehler"); exit(1); } while(fgets(line, sizeof(line), the_file)) { sscanf(line, "%[a-zA-Z];%d", item, &stock); // 拷贝字符串到对应下标的数组空间 strcpy(elements[r2], item); i_stock[r2] = stock; r2++; } printf("%s", elements[2]); fclose(the_file); return 0; }
两种方案都可以实现预期输出Bounty的需求。
内容的提问来源于stack exchange,提问作者Marki75
相关产品推荐
相关产品推荐

