C语言指针与字符串编程:如何修复凯撒密码逻辑错误?
问题修复:实现字符串反转+循环移位功能
原代码存在的关键问题
- 输入处理错误:
scanf的使用方式完全错误——提示文字不应嵌入格式字符串,且未传递变量地址,导致n未被正确赋值;fgets会读取输入末尾的换行符,未处理会干扰后续字符串操作。 - decrypt函数逻辑错误:既没有实现字符串反转,也未完成循环移位,反而使用了越界的数组访问(
cipher + (i + n)),属于未定义行为。
修复后的完整代码
#define MAX 50 void decrypt(char* cipher, int n); int main(void) { int n = 0; char cipher[MAX] = {0}; printf("Enter cipher to decrypt: "); fgets(cipher, sizeof(cipher), stdin); // 移除fgets读取的换行符 size_t len = strlen(cipher); if (len > 0 && cipher[len-1] == '\n') { cipher[len-1] = '\0'; } printf("Enter decryption key: "); scanf("%d", &n); // 正确传递变量地址,单独处理提示文字 decrypt(cipher, n); return 0; } void decrypt(char* cipher, int n) { int len = strlen(cipher); if (len == 0) return; // 第一步:反转字符串 for (int i = 0, j = len - 1; i < j; i++, j--) { char temp = cipher[i]; cipher[i] = cipher[j]; cipher[j] = temp; } // 处理key的范围:转为0-25的有效值,兼容负数和超26的情况 n = n % 26; if (n < 0) { n += 26; } // 第二步:字母循环后移n位 for (int i = 0; i < len; i++) { char c = cipher[i]; if (c >= 'A' && c <= 'Z') { cipher[i] = 'A' + (c - 'A' + n) % 26; } else if (c >= 'a' && c <= 'z') { cipher[i] = 'a' + (c - 'a' + n) % 26; } // 非字母字符保持不变,如需处理可添加对应逻辑 } printf("Result: %s\n", cipher); }
修复说明
- 输入处理:
- 拆分
scanf的提示与格式控制,传递变量地址确保n被正确赋值; - 移除
fgets读取的换行符,避免后续反转/移位操作处理无效字符。
- 拆分
- 字符串反转:
使用双指针法交换首尾字符,完成字符串反转。 - 循环移位:
- 先将
n标准化为0-25的有效值,兼容负数和大于26的输入; - 区分大小写字母,通过模运算实现循环移位(Z后回到A,z后回到a),非字母字符保持原样。
- 先将
测试输入abc和2时,流程为:abc反转得到cba,再分别移位2位得到edc,符合预期输出。
内容的提问来源于stack exchange,提问作者user21501105
相关产品推荐
相关产品推荐

