CS50课程凯撒密码实现问题:字符无输出,仅数字正常
解决CS50凯撒密码实现中的字符无输出问题
嘿,我看到你在CS50凯撒密码作业里遇到了字符无输出的问题——数字正常显示但字母完全没反应,咱们来一步步拆解代码里的核心问题:
问题1:循环边界错误
你的循环条件写的是for (i = 0; i <= strlen(a); i++),但字符串的索引是从0开始到strlen(a)-1的,<=会让你最后访问到字符串末尾的终止符\0,这时候它既不是数字也不是字母,自然不会输出内容,甚至可能引发不必要的内存访问问题。应该改成i < strlen(a)。
问题2:大小写字母的加密逻辑完全错误
这是导致字符无输出的核心原因,你的加密公式逻辑混乱,计算出的ASCII值根本不在有效字母范围内:
- 大写字母处理:你先把
a[i]转成0-25的索引(a[i]-65),但后面直接用a[i] + x%26,再套toupper后又加65,结果会超出字母的ASCII区间。比如'A'(65)加3是68,再加65变成133,这不是有效大写字母,输出的是不可见字符,看起来就像没输出。
正确逻辑应该是:先转成0-25索引,加上偏移量后取模26,再转回大写字母的ASCII值。 - 小写字母处理:不仅犯了和大写一样的逻辑错误,还把小写字母转索引时用了
a[i]-65——小写字母'a'的ASCII是97,减65得到32,根本不是0-25的范围,应该用a[i]-97或者a[i]-'a'。
问题3:偏移量的预处理(优化点)
虽然不是直接导致无输出的原因,但最好先对偏移量x取模26,这样即使输入的偏移量大于26,也能保证加密逻辑正确(比如偏移30和偏移4的效果是一样的)。
修正后的代码
#include <cs50.h> #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> // atoi函数需要的头文件,显式加上更规范 int main (int argc, string argv []) { if (argc != 2){ printf ("Retry\n"); return 1; } // 预处理偏移量,确保在0-25范围内,同时兼容负数偏移(如果作业允许) int x = atoi(argv[1]) % 26; if (x < 0) { x += 26; } string plaintext = get_string ("plaintext: "); printf("ciphertext: "); for (int i = 0; i < strlen(plaintext); i++){ if (isdigit(plaintext[i])){ printf ("%c", plaintext[i]); } else if (isupper(plaintext[i])){ // 转成0-25索引 → 加密偏移 → 转回大写ASCII int shifted = (plaintext[i] - 'A' + x) % 26; printf("%c", shifted + 'A'); } else if (islower(plaintext[i])){ // 小写字母同理处理 int shifted = (plaintext[i] - 'a' + x) % 26; printf("%c", shifted + 'a'); } else { // 保留非字母数字字符(比如空格、标点),符合作业要求 printf("%c", plaintext[i]); } } printf("\n"); // 最后加换行,输出格式更整洁 return 0; }
额外说明
我还补上了原代码缺失的非字母数字字符处理(比如空格、标点),按照CS50作业要求,这些字符应该保持不变,原代码里没处理的话,遇到这类字符也会无输出。
内容的提问来源于stack exchange,提问作者Adam Grey
相关产品推荐
相关产品推荐

