如何将文件文本读取到结构体中的动态数组
问题分析与修正代码
原代码的核心错误
- 内存分配逻辑错误:
char **line是指向指针数组的指针,你需要先分配存储每行指针的数组空间(每个元素是char*类型),再为每个指针单独分配单行的字符内存。原代码直接分配了连续的字符内存,却当作指针数组访问,导致指针地址无效,引发未定义行为。 - 循环条件错误:
while(!feof(inputPtr))的判断时机不对,feof仅在读取操作失败后才会置位,直接用它做循环条件会导致多执行一次无效读取。 - 索引处理错误:
lineIndex是传值调用,函数内的修改无法同步到外部;且初始索引自增后直接访问line[lineIndex],会跳过索引0,还可能导致越界。
修正后的代码
首先建议给结构体增加行数字段,方便后续管理:
typedef struct Text{ char **line; size_t line_count; // 存储总行数 } Text;
然后是修正后的readFile函数:
#define LINE_LENGTH 255 void readFile(FILE *inputPtr, Text *textInFile) { // 初始化结构体字段 textInFile->line = NULL; textInFile->line_count = 0; char buffer[LINE_LENGTH]; // 先读取一行到缓冲区,判断是否成功 while (fgets(buffer, LINE_LENGTH, inputPtr) != NULL) { // 重新分配指针数组的空间:新增一个char*的位置 char **temp_lines = realloc(textInFile->line, (textInFile->line_count + 1) * sizeof(char*)); if (temp_lines == NULL) { // 内存分配失败,释放已分配的内存避免泄漏 for (size_t i = 0; i < textInFile->line_count; i++) { free(textInFile->line[i]); } free(textInFile->line); textInFile->line = NULL; textInFile->line_count = 0; return; } textInFile->line = temp_lines; // 为当前行分配内存,需要包含字符串结束符 textInFile->line[textInFile->line_count] = malloc(strlen(buffer) + 1); if (textInFile->line[textInFile->line_count] == NULL) { // 分配失败,清理已分配资源 for (size_t i = 0; i < textInFile->line_count; i++) { free(textInFile->line[i]); } free(textInFile->line); textInFile->line = NULL; textInFile->line_count = 0; return; } // 复制缓冲区内容到分配的内存 strcpy(textInFile->line[textInFile->line_count], buffer); // 测试打印 printf("%s", textInFile->line[textInFile->line_count]); // 更新行数 textInFile->line_count++; } }
代码说明
- 内存分配逻辑修正:先分配存储指针的数组(
sizeof(char*)),再为每行单独分配字符内存,确保line的每个元素都是有效的字符串指针。 - 循环条件修正:用
fgets的返回值判断是否读取成功,避免feof的陷阱。 - 错误处理:检查
realloc和malloc的返回值,分配失败时清理已分配的内存,防止内存泄漏。 - 行数管理:通过结构体的
line_count字段记录总行数,方便后续对文本的操作。 - 缓冲区使用:先用栈上的缓冲区读取内容,再分配内存复制,避免直接用
fgets写入未初始化的堆内存。
使用注意
调用该函数后,不再使用文本内容时,需要手动释放内存:
void freeText(Text *text) { for (size_t i = 0; i < text->line_count; i++) { free(text->line[i]); } free(text->line); text->line = NULL; text->line_count = 0; }
内容的提问来源于stack exchange,提问作者vabalas
相关产品推荐
相关产品推荐

