C语言数组无法保留值:读取文本文件时元素被覆盖问题
问题分析与修复:数组元素被覆盖的原因及解决办法
核心问题
你的代码里char* posList[50];是一个指针数组,每次循环执行posList[lineCnt] = line;时,只是把栈上固定数组line的地址赋值给了指针元素。而fgets每次都会把新读取的内容写入同一个line数组,所以所有posList里的指针最终都指向同一块内存空间——最后一次fgets写入的内容自然会覆盖之前的所有"假象"。
两种可行的修复方案
方案1:为每个指针分配独立内存
使用malloc为每个字符串分配单独的内存空间,再用strcpy把line里的内容复制过去:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_LENGTH 16 #define MAX_LINES 50 int main() { int lineCnt = 0; FILE *textfile; char line[MAX_LINE_LENGTH]; char* posList[MAX_LINES]; textfile = fopen("pos-list.txt", "r"); if(textfile == NULL) { system("cls"); fprintf(stderr, "**File open failed\n Make sure there is a pos-list.txt file"); return 1; } system("cls"); while(fgets(line, MAX_LINE_LENGTH, textfile) && lineCnt < MAX_LINES) { // 去掉换行符(可选,根据需求调整) line[strcspn(line, "\n")] = '\0'; // 分配内存并复制内容 posList[lineCnt] = malloc(strlen(line) + 1); if(posList[lineCnt] == NULL) { fprintf(stderr, "Memory allocation failed"); // 释放已分配的内存再退出 for(int i=0; i<lineCnt; i++) free(posList[i]); fclose(textfile); return 1; } strcpy(posList[lineCnt], line); printf("Line %d: %s\n", lineCnt, line); printf("posList[%d] = %s\n", lineCnt, posList[lineCnt]); printf("posList[0] = %s\n", posList[0]); lineCnt++; } // 使用完后释放内存,避免泄漏 for(int i=0; i<lineCnt; i++) { free(posList[i]); } fclose(textfile); return 0; }
方案2:使用二维数组直接存储字符串
如果预先知道最大行数和每行长度,可以直接定义二维数组,避免动态内存分配:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_LENGTH 16 #define MAX_LINES 50 int main() { int lineCnt = 0; FILE *textfile; char posList[MAX_LINES][MAX_LINE_LENGTH]; // 二维数组,每个元素是独立的字符串 textfile = fopen("pos-list.txt", "r"); if(textfile == NULL) { system("cls"); fprintf(stderr, "**File open failed\n Make sure there is a pos-list.txt file"); return 1; } system("cls"); while(fgets(posList[lineCnt], MAX_LINE_LENGTH, textfile) && lineCnt < MAX_LINES) { // 去掉换行符(可选) posList[lineCnt][strcspn(posList[lineCnt], "\n")] = '\0'; printf("Line %d: %s\n", lineCnt, posList[lineCnt]); printf("posList[%d] = %s\n", lineCnt, posList[lineCnt]); printf("posList[0] = %s\n", posList[0]); lineCnt++; } fclose(textfile); return 0; }
额外优化点
- 移除了无用的
lineCntPOSlist和i变量,简化代码结构 - 增加
lineCnt < MAX_LINES判断,防止数组越界 - 加入换行符去除逻辑(
strcspn),避免字符串携带多余换行符 - 方案1补充了内存分配失败的异常处理,以及使用后的内存释放逻辑
内容的提问来源于stack exchange,提问作者deo406
相关产品推荐
相关产品推荐

