为何我的替换密码代码无法输出预期密文?
问题排查与修复方案
核心错误点
- 覆盖赋值导致大小写失效:在匹配到目标字符后,你先判断原字符是小写并将
cipher[i]设为小写密钥字符,但紧接着执行的cipher[i] = tmpKey;直接覆盖了之前的转换结果,最终输出全是密钥的大写字符——这就是输入hello得到MOAAB的根本原因。 - 低效的字符匹配逻辑:通过双层循环遍历26个字母找匹配的方式不仅冗余,还容易因循环逻辑细节出错,其实可以通过ASCII值计算直接定位索引。
修复后的代码
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> string cipher_word(string key, string text) { for (int i = 0; text[i] != '\0'; i++) { char c = text[i]; if (isalpha(c)) { // 统一转大写计算字母表索引,A/a对应0,B/b对应1... int index = toupper(c) - 'A'; char key_char = key[index]; // 按原字符大小写调整结果 text[i] = islower(c) ? tolower(key_char) : toupper(key_char); } // 非字母字符保持原样 } return text; } int main(int argc, string argv[]) { string key = get_string("What is the key? "); string text = get_string("What text do you want to cipher? "); string cipher = cipher_word(key, text); printf("%s\n", cipher); }
修复说明
- 简化索引计算:通过
toupper(c) - 'A'直接得到字符在字母表中的位置,无需循环匹配,既高效又避免逻辑错误。 - 精准保留大小写:先判断原字符的大小写,再将密钥对应字符转换为相同格式,彻底解决大小写丢失问题。
- 消除冗余赋值:直接一次性设置结果字符,不会出现先转小写再被大写覆盖的情况。
测试验证
输入密钥VCHPRZGJNTLSKFBDQWAXEUYMOI时:
- 输入
Hello,输出jrssb - 输入
hello,输出jrssb - 输入
HELLO,输出JRSSB
完全符合预期要求。
内容的提问来源于stack exchange,提问作者Tolunay tas
相关产品推荐
相关产品推荐

