C语言中使用printf无法打印rotate函数返回字符的问题求助
凯撒密码实现问题排查与修复
问题描述
实现凯撒密码时,调用char rotate(char c, int n)函数后仅能打印数字而非字符,输入abc时仅显示plaintext: ,无密文输出。相关代码如下:
#include <cs50.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> bool only_digits(string arg); char rotate(char c, int n); int main(int argc, string argv[]) { // Make sure program was run with just one command-line argument if (argc !=2) { printf("Usage: ./caesar key\n"); return 1; }; // Make sure every character in argv[1] is a digit if ( only_digits(argv[1])==0) { printf("Usage: ./caesar key\n"); return 1; }; // Convert argv[1] from a `string` to an `int` int key = atoi(argv[1]); // Prompt user for plaintext// string text = get_string("plaintext: \n"); // For each character in the plaintext: printf("ciphertext: "); for (int i = 0; i < strlen(text); i++) { char ch = (rotate(text[i], key)); printf("%c", ch); }; } bool only_digits(string arg) { // Rotate the character if it's a letter for (int i = 0; i < strlen(arg); i++) { if (!isdigit(arg[i])) { return false; } } return true; } char rotate(char c, int n){ if (isupper(c)) { c -=65; c = (c + n) % 26; c = c + '0'; return c; } else if (islower(c)) { c -=97; c = (c + n) % 26; c = c + '0'; return c; } else return c; }
错误分析
核心问题出在rotate函数的字符转换逻辑:
- 处理大写字母时,偏移计算完成后,错误地使用
c = c + '0'将数值转为数字字符(ASCII码48-57),而非大写字母(ASCII码65-90)。 - 处理小写字母时同理,应该加
'a'(ASCII码97)转回小写字母,而非'0'。 - 当输入
abc这类小写字母时,偏移后的数值加'0'得到的是不可打印字符或非预期字符,导致终端无正常密文显示。
修复后的代码
#include <cs50.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> bool only_digits(string arg); char rotate(char c, int n); int main(int argc, string argv[]) { // 确保程序仅接收一个命令行参数 if (argc != 2) { printf("Usage: ./caesar key\n"); return 1; } // 确保命令行参数全为数字 if (!only_digits(argv[1])) { printf("Usage: ./caesar key\n"); return 1; } // 将字符串参数转为整数密钥 int key = atoi(argv[1]); // 提示用户输入明文 string text = get_string("plaintext: "); // 输出密文前缀 printf("ciphertext: "); // 遍历明文字符并转换 for (int i = 0; i < strlen(text); i++) { char ch = rotate(text[i], key); printf("%c", ch); } printf("\n"); // 增加换行,使输出格式更规范 } bool only_digits(string arg) { for (int i = 0; i < strlen(arg); i++) { if (!isdigit(arg[i])) { return false; } } return true; } char rotate(char c, int n) { if (isupper(c)) { c -= 'A'; // 用字符常量替代魔法数字65,可读性更强 c = (c + n) % 26; c += 'A'; // 转回大写字母 return c; } else if (islower(c)) { c -= 'a'; // 用字符常量替代魔法数字97 c = (c + n) % 26; c += 'a'; // 转回小写字母 return c; } else { return c; // 非字母字符直接返回 } }
额外优化说明
- 替换了魔法数字65、97为
'A'、'a',提升代码可读性。 - 移除了代码中多余的分号(如
if语句块后的分号),避免潜在语法问题。 - 在密文输出末尾增加换行符,使终端输出格式更整洁。
内容的提问来源于stack exchange,提问作者Wadah
相关产品推荐
相关产品推荐

