如何解决C语言带字符串的结构体字典排序失效且输出乱码问题
问题根源定位
1. 排序失效的核心诱因
sortString函数存在循环代码块边界错误,直接导致排序逻辑完全失效:
按照C语言语法规则,没有大括号包裹的循环,仅会将紧随其后的第一行语句作为循环体。原代码中j的内层循环未加大括号,实际执行流程为:
for (i =0; i < entries; ++i) { // 内层for循环仅执行单条赋值语句:遍历j从i+1到末尾,不断覆盖result的值 for (j=i+1; j < entries; ++j) result = compareString(dictionary[i].word, dictionary[j].word); // 内层循环全部结束后,才执行一次交换判断 if (result < 0) { // 字段交换操作 } }
该实现完全不具备选择排序的核心逻辑:没有逐次遍历j位置元素并及时交换的流程,仅在每个i位置和数组最后一个元素做单次比较,无法形成正确的字典序排列。
2. 输出乱码的触发逻辑
由于循环逻辑错位,result变量存储的是j循环最后一次迭代的比较结果,一旦满足交换条件,strcpy操作的字符串拷贝边界完全失控,会将结构体数组外的随机内存值拷贝到结构体的字符串成员中,最终打印时就会输出无意义的乱码字符。
附加逻辑偏差
原代码的交换判断方向和字典序升序的目标完全相反:
- 自定义
compareString的返回规则为:s1字典序小于s2时返回-1,s1大于s2时返回1 - 原代码设置当
result <0(i位置单词字典序小于j位置单词)时才触发交换,这会将字典序更大的单词前置,最终生成降序排列结果,和预期的a-z升序目标不一致。
修正方案
- 为j的内层for循环添加大括号,将比较、判断、交换的全流程逻辑纳入循环体,保证每次j的遍历都执行完整的比较操作
- 调整交换判断条件:当i位置的单词字典序大于j位置的单词时触发交换,匹配升序排列需求
- 临时变量长度匹配结构体成员数组的大小,避免不必要的资源占用
修正后的sortString函数参考实现:
void sortString (struct entry dictionary[], int entries) { int i,j; int result; char tempWord[15]; char tempDef[50]; // 外层循环仅需遍历到倒数第二个元素,末位元素无后续节点可比较 for (i =0; i < entries - 1; ++i) { // 全流程纳入内层循环块 for (j=i+1; j < entries; ++j) { result = compareString(dictionary[i].word, dictionary[j].word); // i位置字典序更大时执行交换,实现升序 if (result > 0) { strcpy(tempWord, dictionary[i].word); strcpy(tempDef, dictionary[i].definition); strcpy(dictionary[i].word, dictionary[j].word); strcpy(dictionary[i].definition, dictionary[j].definition); strcpy(dictionary[j].word, tempWord); strcpy(dictionary[j].definition, tempDef); } } } }
内容的提问来源于stack exchange,提问作者stephen Ong
相关产品推荐
相关产品推荐

