如何将文本文件内容存入二维数组并解决单词统计读取异常问题
问题排查与解决方案
我来帮你搞定这个单词统计的问题!从你描述的情况和给出的代码片段来看,核心问题出在没有正确实现单词拆分逻辑,再加上fgets的使用方式不符合二维数组存储单词的需求,才导致只输出了前两个单词。咱们一步步拆解并修复:
问题根源分析
fgets的使用误区:你用fgets(word2, sizeof...)读取文件,但word2是二维数组,fgets会把整行内容直接塞进word2[0]这一行里,而不是自动拆分单词到不同的行。- 缺失单词分割逻辑:代码里只打开了文件、尝试读取,但没有判断空格、标点来拆分单词,也没有把每个单词存入二维数组的对应行。
- 字符串终止符缺失:就算读取了字符,没有手动添加
'\0',C语言也无法识别为有效的字符串,会导致输出异常。
修复后的完整代码
下面是实现了正确单词拆分逻辑的代码,适配你[200][20]的二维数组需求:
#include <stdio.h> #include <string.h> #include <ctype.h> #define MAX_WORDS 200 // 对应你的[200]维度,最多存200个单词 #define MAX_WORD_LEN 20 // 对应你的[20]维度,每个单词最多19个字符(留1位存'\0') void countwords(char word2[MAX_WORDS][MAX_WORD_LEN]){ FILE *read; char current_char; int word_index = 0; // 当前要存储的单词在二维数组中的行索引 int char_index = 0; // 当前单词的字符索引 int is_in_word = 0; // 标记是否正在读取一个单词 // 打开文件 if((read = fopen("thetext.txt", "rt")) == NULL){ printf("Cannot open File."); return; } // 逐个读取字符,拆分单词 while((current_char = fgetc(read)) != EOF){ // 判断当前字符是否属于单词(字母或缩写用的撇号) if(isalpha(current_char) || current_char == '\''){ if(!is_in_word){ // 新单词开始,重置字符索引 char_index = 0; is_in_word = 1; } // 避免单词长度超过数组限制 if(char_index < MAX_WORD_LEN - 1){ word2[word_index][char_index++] = current_char; } } else { // 遇到非单词字符,结束当前单词 if(is_in_word){ // 添加字符串终止符,让C能识别为有效字符串 word2[word_index][char_index] = '\0'; // 移动到下一个单词的行 word_index++; // 防止超过最大单词数,避免数组越界 if(word_index >= MAX_WORDS){ break; } is_in_word = 0; } } } // 处理文件末尾的最后一个单词(避免因为没有分隔符而丢失) if(is_in_word){ word2[word_index][char_index] = '\0'; word_index++; } fclose(read); // 测试输出所有提取到的单词 printf("提取到的所有单词:\n"); for(int i = 0; i < word_index; i++){ printf("%s\n", word2[i]); } } int main(){ char word_array[MAX_WORDS][MAX_WORD_LEN]; countwords(word_array); return 0; }
关键修复点说明
- 用
fgetc逐个处理字符:相比fgets,能精确控制单词的分割,完美匹配二维数组一行存一个单词的需求。 - 添加单词状态标记:通过
is_in_word区分“正在读取单词”和“处于分隔符”状态,准确拆分每个单词。 - 数组越界保护:限制单词数量和单个单词长度,避免内存溢出问题。
- 手动添加
'\0':每个单词末尾必须加终止符,否则无法正常输出C字符串。
运行这段代码后,就能把文件里的所有单词都存入二维数组,并且完整输出啦!
内容的提问来源于stack exchange,提问作者Karen Jangra
相关产品推荐
相关产品推荐

