C语言函数存储文件名到数组时所有元素均为最后一项的问题
C语言读取文件名到数组后重复显示最后一个元素的问题解决
问题原因
你遇到的问题核心是数组中所有元素都指向了同一个局部变量Buff的内存地址:
Buff是函数内的局部数组,它的内存地址在整个函数运行期间固定不变。- 每次循环你用
strcpy把新名字写入Buff,然后执行Array[a] = Buff——这一步不是复制字符串内容,只是把Buff的地址赋值给数组元素。 - 所以数组里的所有元素本质上都是同一个地址的引用,最后一次循环把
name4写入Buff后,所有元素指向的都是这块存着name4的内存空间,第二次循环打印时自然全是name4。
修正方案
方案1:动态分配独立内存(推荐)
为每个名字单独分配内存,让数组元素指向不同的内存块,确保每个字符串都有独立的存储空间:
void Names(char *Txt, char **Array) { FILE *Text = fopen(Txt, "r"); if (!Text) { // 必须检查文件是否成功打开 perror("fopen failed"); return; } int a = 0; const int Buffer = 150; char string[Buffer]; while (fgets(string, Buffer, Text) != NULL) { char *token = strtok(string, " ,\n"); if (token == NULL) continue; // 跳过空行或无有效内容的行 // 分配足够内存:字符串长度 + 1 用于存储终止符 '\0' Array[a] = malloc(strlen(token) + 1); if (!Array[a]) { // 检查内存分配是否成功 perror("malloc failed"); fclose(Text); return; } strcpy(Array[a], token); printf("%s\n", Array[a]); a++; } int c = 0; while (c < a) { printf("%s\n", Array[c]); c++; } fclose(Text); // 别忘了关闭文件,避免资源泄漏 }
注意:调用该函数后,需要在外部通过
free()逐个释放数组中的内存,防止内存泄漏。
方案2:使用二维数组存储(适合固定大小场景)
如果提前知道最多需要存储的名字数量和单个名字的最大长度,可以用二维数组直接存储,每个元素拥有独立的存储空间:
// 定义最大存储数量和单名字长度 #define MAX_NAMES 100 #define MAX_NAME_LENGTH 25 void Names(char *Txt, char Array[MAX_NAMES][MAX_NAME_LENGTH]) { FILE *Text = fopen(Txt, "r"); if (!Text) { perror("fopen failed"); return; } int a = 0; const int Buffer = 150; char string[Buffer]; while (fgets(string, Buffer, Text) != NULL && a < MAX_NAMES) { char *token = strtok(string, " ,\n"); if (token == NULL) continue; // 用strncpy避免数组越界,手动添加终止符 strncpy(Array[a], token, MAX_NAME_LENGTH - 1); Array[a][MAX_NAME_LENGTH - 1] = '\0'; printf("%s\n", Array[a]); a++; } int c = 0; while (c < a) { printf("%s\n", Array[c]); c++; } fclose(Text); }
额外注意点
- 原代码未检查
fopen的返回值,实际开发中必须添加,否则文件打开失败会导致空指针操作崩溃。 strtok会修改传入的原字符串,且需要处理返回NULL的情况(比如遇到空行)。- 局部变量的内存仅在函数执行期间有效,如果后续外部需要继续使用数组内容,动态分配内存的方案更灵活;二维数组方案则适合内存大小固定的场景。
内容的提问来源于stack exchange,提问作者TheEseck1
相关产品推荐
相关产品推荐

