如何将文件单词存入字符串动态数组?代码存值异常求助
问题分析与修复
你的代码存在几个关键问题,直接导致了错误输出:
文件指针未重置
第一次用while(fscanf(...))统计单词数后,文件指针已经移动到文件末尾,后续的fscanf无法读取到新内容,此时word里保留的是最后一次读取的单词,后续循环相当于重复使用这个旧值。指针指向错误
list_of_words[i] = word;这行代码是把每个数组元素都指向了同一个局部数组word的地址,而非复制单词内容。每次循环word被新内容覆盖,最终所有指针都指向word的最后一次值,所以打印时全是最后一个单词。而且你之前malloc的内存被直接覆盖,造成内存泄漏。越界修改字符串
word[length+1] = '\0';是错误操作:strlen(word)得到的是字符串的有效长度(不含末尾的\0),fscanf读取%s时已经自动在word末尾添加了\0,修改length+1的位置会超出数组的合法下标(比如word是20字节,下标范围是0-19,若length为19,length+1就是20,属于越界访问)。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *file = fopen("words.txt", "r"); // 检查文件是否成功打开 if (!file) { perror("无法打开文件"); return 1; } char word[20]; int words_count = 0; // 第一次遍历统计单词数 while (fscanf(file, "%s", word) != EOF) { words_count++; } printf("单词总数:%d\n", words_count); // 将文件指针重置到文件开头 rewind(file); // 分配指针数组内存 char **list_of_words = malloc(words_count * sizeof(char *)); if (!list_of_words) { perror("内存分配失败"); fclose(file); return 1; } for (int i = 0; i < words_count; i++) { fscanf(file, "%s", word); int length = strlen(word); // 分配单个单词的内存(+1 是为了存储末尾的'\0') list_of_words[i] = malloc((length + 1) * sizeof(char)); if (!list_of_words[i]) { perror("单词内存分配失败"); // 已分配的内存要释放,避免泄漏 for (int j = 0; j < i; j++) { free(list_of_words[j]); } free(list_of_words); fclose(file); return 1; } // 复制单词内容到分配的内存中 strcpy(list_of_words[i], word); } // 打印所有单词 printf("读取的单词:\n"); for (int i = 0; i < words_count; i++) { printf("%s\n", list_of_words[i]); } // 释放内存 for (int i = 0; i < words_count; i++) { free(list_of_words[i]); } free(list_of_words); fclose(file); return 0; }
关键修改说明
- 添加
fopen的错误检查,避免文件打开失败时后续操作崩溃。 - 统计完单词数后,用
rewind(file)将文件指针移回文件开头,确保后续能重新读取内容。 - 分配单个单词内存后,用
strcpy把word的内容复制到分配的内存中,而非直接赋值指针,这样每个数组元素都指向独立的内存空间。 - 添加内存分配的错误检查,避免内存分配失败时出现问题,同时在出错时释放已分配的内存,防止泄漏。
- 程序结束前释放所有动态分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Basel Eyad
相关产品推荐
相关产品推荐

