为何strcmp()在字典序首尾单词判定程序中无法识别最小单词?
问题分析:字典序最小单词判定失效的原因及修复方案
你遇到的问题核心在于全局变量smallest和largest没有正确初始化,导致第一个if分支永远无法触发。
问题根源解释
在C语言中,全局字符数组会默认被初始化为全0(也就是空字符串"")。而空字符串在字典序里是最小的——所有你输入的单词(比如dog、zebra)的字典序都比空字符串大。
这就导致:
- 每次输入单词时,
strcmp(str, smallest)的结果都是正数(因为输入的单词比空串大),第一个if的条件strcmp(str, smallest) < 0永远不成立,自然不会进入分支更新smallest。 - 而
largest的初始值也是空串,所有输入的单词都比它大,所以else if分支能正常触发,这就是为什么你的输出里largest是正常的,smallest却一直为空。
修复方案
我们需要把第一个输入的单词作为smallest和largest的初始基准,这样后续的比较才有合理的参照。修改后的代码如下:
#include <stdio.h> #include <string.h> void getword(void); char str[20]; char smallest[20]; char largest[20]; int main(int argc, char *argv[]) { // 先读取第一个单词,初始化最小和最大值 getword(); strcpy(smallest, str); strcpy(largest, str); // 继续读取单词,直到输入4个字母的单词 while (strlen(str) != 4) { getword(); // 如果当前输入是终止用的4字母单词,直接退出循环 if (strlen(str) == 4) { break; } // 更新最小单词 if (strcmp(str, smallest) < 0) { strcpy(smallest, str); } // 更新最大单词 else if (strcmp(str, largest) > 0) { strcpy(largest, str); } } printf("smallest:%s\nlargest:%s\n", smallest, largest); return 0; } void getword(void) { printf("Enter a word: "); scanf("%s", str); }
关键修改说明
- 初始化基准值:先读取第一个单词,直接把它复制到
smallest和largest,让后续的比较有了正确的起点。 - 提前终止判断:在循环里增加了判断,如果刚输入的是4字母单词,直接退出循环,避免把这个终止用的单词纳入比较(如果需要把它也算进结果,也可以调整为先比较再判断退出)。
测试验证
用你提供的输入测试:
Enter a word: dog Enter a word: zebra Enter a word: rabbit Enter a word: catfish Enter a word: walrus Enter a word: cat Enter a word: fish
程序会在输入fish(4个字母)时停止,输出:
smallest:cat largest:zebra
这就符合预期了。
额外优化建议
- 可以考虑把
str、smallest、largest改成局部变量,通过参数传递的方式在函数间共享,减少全局变量带来的潜在问题。 - 可以增加输入长度的校验,避免用户输入超过20字符的单词导致缓冲区溢出。
内容的提问来源于stack exchange,提问作者proprogrammer32987
相关产品推荐
相关产品推荐

