C语言结构体字符串处理异常:词频统计结果不符合预期
C语言单词频率统计问题修复
问题描述
我在使用C语言结构体处理字符串时遇到问题,怀疑和strcpy()有关但解决不了。练习要求编写程序:输入若干单词,输出不同单词并按出现频率降序排列,每个单词前标注出现次数。我试过把scanf()换成fgets(),问题依然存在。以下是我的代码(还没实现按频率排序的函数):
原代码
/* Write a program that prints the distinct words given as input, sorted in order of frequency of decreasing occurrence. Precede each word with its number of occurrences. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #define SIZE 30 #define MAXWORD 5 typedef struct word_dictionary{ char ww[SIZE]; int occ; } word; int is_in_bucket(char *str, word data[]){ int j; for(j=0;j<MAXWORD;j++){ if( strcmp(str,data[j].ww) == 0) return 1; } return 0; } void print_bucket(word data[]) { int i; for(i=0;i<MAXWORD;i++){ printf("{%d, %s} ", data[i].occ, data[i].ww); } printf("\n"); } void main( int argc, char **argv) { word bucket[MAXWORD]; char aux[SIZE]; int i; int x; int cond; for(i=0;i<MAXWORD;i++) { printf("Insert the word you want to save in the data structure: "); scanf("%s",aux); cond = is_in_bucket(aux,bucket); if(cond == 1) { bucket[i].occ = bucket[i].occ + 1; memset(aux,0,SIZE); } else { strcpy(bucket[i].ww, aux); bucket[i].occ = 1; memset(aux,0,SIZE); } } print_bucket(bucket); // print_occurrences(); return; }
实际输出
Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: cat Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: mouse {1, dog} {1, cat} {-1768437999, } {1, V} {1, mouse}
预期输出
Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: cat Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: dog Insert the word you want to save in the data structure: mouse {3, dog} {1, cat} {1, mouse}
问题分析与修复
核心错误点
- 结构体数组未初始化:
bucket数组的元素没有初始化,ww字段是随机内存中的垃圾字符串,occ是随机整数,导致strcmp判断错误,输出出现乱码。 - 重复单词处理逻辑错误:
is_in_bucket只返回是否存在,没有返回对应单词的索引。当检测到重复时,错误地修改当前循环i位置的occ,而不是找到的那个重复单词的occ。 - 打印逻辑错误:遍历所有
MAXWORD个元素,包括未使用的空元素,导致输出无效内容。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 30 #define MAXWORD 5 typedef struct word_dictionary{ char ww[SIZE]; int occ; } word; // 返回单词在数组中的索引,不存在返回-1 int find_word_index(char *str, word data[]) { for(int j = 0; j < MAXWORD; j++) { // 只判断已初始化的元素(occ>0说明已经存了单词) if(data[j].occ > 0 && strcmp(str, data[j].ww) == 0) { return j; } } return -1; } void print_bucket(word data[]) { for(int i = 0; i < MAXWORD; i++) { // 只打印有有效数据的元素 if(data[i].occ > 0) { printf("{%d, %s} ", data[i].occ, data[i].ww); } } printf("\n"); } int main() { word bucket[MAXWORD] = {0}; // 初始化所有元素为0,ww会被设为空字符串,occ为0 char aux[SIZE]; int count = 0; // 记录已存储的不同单词数量 for(int i = 0; i < MAXWORD; i++) { printf("Insert the word you want to save in the data structure: "); scanf("%s", aux); int idx = find_word_index(aux, bucket); if(idx != -1) { // 找到重复单词,增加对应索引的occ bucket[idx].occ++; } else { // 新单词,存入第一个空位置 if(count < MAXWORD) { strcpy(bucket[count].ww, aux); bucket[count].occ = 1; count++; } else { printf("单词数量已达上限\n"); } } } print_bucket(bucket); return 0; }
修复说明
- 初始化结构体数组:用
= {0}初始化,确保ww为空字符串,occ为0,避免垃圾数据干扰。 - 修改查找函数:
find_word_index返回单词的索引,方便直接修改对应元素的occ,同时只判断已初始化的元素(occ>0)。 - 调整存储逻辑:用
count记录已存储的不同单词数量,新单词存入count位置,避免占用未使用的索引。 - 优化打印逻辑:只打印
occ>0的有效元素,不再输出垃圾内容。
内容的提问来源于stack exchange,提问作者Numero8
相关产品推荐
相关产品推荐

