C程序词频统计异常求助:文本与关键词对比并降序输出
问题排查:C程序关键词频率统计异常
需求与预期输出
需实现功能:读取用户指定的文本文件,与keyword.txt中的关键词对比,统计每个关键词的出现频率,并按降序输出。
预期输出格式:
euery 8 common 8 gaue 7 thankes 5 vnkle 4 growes 3 wag 3 seal 3 day 3 soft 3
当前代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_FILENAME_LENGTH 256 #define MAX_TEXT_LENGTH 100000 #define MAX_KEYWORDS 100 // Structure to store keyword frequencies typedef struct KeywordFrequency { char keyword[50]; int frequency; } KeywordFrequency; // Compare function for sorting keyword frequencies int compareKeywords(const void *a, const void *b) { return ((KeywordFrequency *)b)->frequency - ((KeywordFrequency *)a)->frequency; } int main() { char filename[MAX_FILENAME_LENGTH]; char text[MAX_TEXT_LENGTH]; KeywordFrequency keywords[MAX_KEYWORDS]; int totalKeywords = 0; // Ask the user for the name of the text file printf("Enter the name of the text file: "); scanf("%s", filename); // Open and read the text file FILE *textFile = fopen(filename, "r"); if (textFile == NULL) { printf("Error opening %s\n", filename); return 1; } // Read the content of the text file fread(text, 1, sizeof(text), textFile); fclose(textFile); // Open and read the keyword file FILE *keywordFile = fopen("keyword.txt", "r"); if (keywordFile == NULL) { printf("Error opening keyword.txt\n"); return 1; } // Initialize keyword frequencies while (fscanf(keywordFile, "%s", keywords[totalKeywords].keyword) != EOF) { keywords[totalKeywords].frequency = 0; totalKeywords++; } fclose(keywordFile); // Tokenize and compare the text with keywords char *token = strtok(text, " "); while (token != NULL) { for (int i = 0; i < totalKeywords; i++) { if (strcmp(token, keywords[i].keyword) == 0) { keywords[i].frequency++; } } token = strtok(NULL, " "); } // Sort keyword frequencies in descending order qsort(keywords, totalKeywords, sizeof(KeywordFrequency), compareKeywords); // Print the results in a table format printf("Keyword\tFrequency\n"); for (int i = 0; i < totalKeywords; i++) { printf("%s\t%d\n", keywords[i].keyword, keywords[i].frequency); } return 0; }
关键问题与修复方案
文本读取未添加字符串终止符:
fread不会自动在读取的文本末尾添加\0,导致strtok无法正确识别字符串边界,引发错误分词或内存越界。修复代码:// 读取文本时预留1字节存放终止符 size_t bytesRead = fread(text, 1, sizeof(text)-1, textFile); text[bytesRead] = '\0';分词分隔符不完整:仅用空格作为分隔符,无法处理文本中的标点(如逗号、句号、换行),导致关键词与标点粘连(如
euery.),无法匹配关键词。修复分隔符集合:char *token = strtok(text, " \n\t.,!?;:\"'");关键词数组越界风险:未限制
totalKeywords不超过MAX_KEYWORDS,若keyword.txt中关键词数量超过100,会导致数组越界。修复读取逻辑:while (totalKeywords < MAX_KEYWORDS && fscanf(keywordFile, "%s", keywords[totalKeywords].keyword) != EOF) { keywords[totalKeywords].frequency = 0; totalKeywords++; }输出格式不符合预期:当前输出包含表头且用制表符分隔,与预期的“关键词+空格+频率”格式不符。修改输出代码:
for (int i = 0; i < totalKeywords; i++) { printf("%s %d\n", keywords[i].keyword, keywords[i].frequency); }
内容的提问来源于stack exchange,提问作者kristian williams
相关产品推荐
相关产品推荐

