CS50 Week2凯撒密码练习:加密输出仅显示空格无字符问题求助
凯撒密码代码问题修复
问题根源
你的代码输出空白是因为错误地直接对ASCII值取模26:
- 字母的ASCII值(如'A'=65、'a'=97)远大于26,将
cipher + key对26取模后得到0-25之间的数值,这些对应ASCII控制字符(不可打印或显示为空白)。 - 另外还有两个关键问题:
- 先解析
key再检查参数数量,无参数时访问argv[1]会触发未定义行为。 - 未区分大小写字母,也未保留非字母字符(如数字、符号)。
- 先解析
修复方案与代码
1. 先校验参数合法性
在解析key前先检查argc是否为2,避免非法访问数组越界。
2. 分类型处理字符
- 大写字母:基于'A'(65)转换为0-25范围后计算偏移,再转回ASCII
- 小写字母:基于'a'(97)做类似处理
- 非字母字符:直接输出,不做偏移
修正后的完整代码
#include <cs50.h> #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> int main(int argc, string argv[]) { // 先检查参数数量是否正确 if (argc != 2) { printf("Usage: ./ceasar key\n"); return 1; // 返回错误码标记异常 } int key = atoi(argv[1]); // 可选:确保key为非负整数 if (key < 0) { printf("Key must be a non-negative integer.\n"); return 1; } string text = get_string("Plaintext: "); printf("Ciphertext: "); for (int i = 0, len = strlen(text); i < len; i++) { char c = text[i]; if (isupper(c)) { // 大写字母偏移逻辑 printf("%c", ((c - 'A') + key) % 26 + 'A'); } else if (islower(c)) { // 小写字母偏移逻辑 printf("%c", ((c - 'a') + key) % 26 + 'a'); } else { // 非字母直接输出 printf("%c", c); } } printf("\n"); return 0; }
核心逻辑说明
(c - 'A'):把大写字母映射到0-25的索引范围(A对应0,Z对应25)+ key:应用指定的偏移量%26:处理循环偏移(比如Z偏移1后回到A)+ 'A':把计算后的索引转回ASCII大写字母范围
修改后即可正确输出加密后的字母,同时保留数字、符号等非字母字符,参数校验也更安全。
内容的提问来源于stack exchange,提问作者Alec
相关产品推荐
相关产品推荐

