字符串数组插入排序代码问题排查:最长字符串反转输出程序
你的C程序问题分析与修复
核心问题定位
你代码里的问题不止一处,直接导致程序逻辑错误甚至崩溃:
- 排序逻辑完全偏离需求:你要找最长字符串,但当前插入排序用
strcmp比较字典序,不是字符串长度,排序后最后一个元素只是字典序最大的,不是最长的。 - 数组越界bug:while循环里写了
(j >= 0),但j是外层循环变量,从1开始一直大于等于1,这个条件永远为真。当o递减到-1时,还会去访问strings[o](也就是strings[-1]),这属于数组越界,会触发未定义行为(比如崩溃、输出乱码)。
修复方案
方案1:直接找最长字符串(效率更高,无需排序)
其实没必要用插入排序,遍历一遍数组就能找到最长的字符串,代码更简洁:
#include <stdio.h> #include <stdlib.h> #include <string.h> static void fatal(const char *msg) { fprintf(stderr, "%s\n", msg); exit(EXIT_FAILURE); } // 自定义字符串反转函数,替代非标准的strrev char* reverse_str(char *str) { if (!str) return str; char *start = str; char *end = str + strlen(str) - 1; char temp; while (start < end) { temp = *start; *start = *end; *end = temp; start++; end--; } return str; } int main(void) { int n; printf("How many strings do you want to enter? "); if (1 != scanf("%d", &n) || 1 > n || n > 32) fatal("Invalid size specified."); char strings[n][64]; for (int i = 0; i < n; i++) { printf("Please enter string #%d: ", i + 1); if (1 != scanf("%63s", strings[i])) fatal("Invalid string input."); } // 找最长字符串 int longest_idx = 0; size_t max_len = strlen(strings[0]); for (int i = 1; i < n; i++) { size_t len = strlen(strings[i]); if (len > max_len) { max_len = len; longest_idx = i; } } // 反转并输出 puts(reverse_str(strings[longest_idx])); return 0; }
方案2:修正插入排序(按长度排序)
如果一定要保留插入排序的逻辑,需要修改两个核心点:
- 把while循环的
j >=0改成o >=0 - 把
strcmp(selected, strings[o]) > 0改成strlen(selected) > strlen(strings[o]) - 替换非标准的
strrev为自定义反转函数
修正后的插入排序部分代码:
char selected[100]; int o; int j; for (j = 1; j < n; j++) { strcpy(selected, strings[j]); o = j - 1; // 修正循环条件和比较逻辑 while ((o >= 0) && (strlen(selected) > strlen(strings[o]))) { strcpy(strings[o+1], strings[o]); o--; } strcpy(strings[o + 1], selected); }
额外提示
strrev不是C标准库函数,只有部分编译器(比如MSVC)支持,在GCC等编译器下会报错,所以建议用自定义的reverse_str函数,保证代码可移植性。
内容的提问来源于stack exchange,提问作者Mani Aghaie
相关产品推荐
相关产品推荐

