如何修复C语言ROT13加密程序处理f及之后字母时出现问号的问题
问题原因
你遇到的问题核心是默认char类型为带符号类型(signed char),取值范围为-128~127。
ASCII码中'a'为97,'z'为122。当你处理's'到'z'范围的字母时,加13后的结果为128~135,超过signed char的最大值127,发生整数溢出变为负数。此时if(ch > 'z')的判断条件不成立(负数必然小于122),不会执行减26的修正逻辑,最终存储的非法值输出时就会显示为问号。
前面'n'到'r'加13后的结果为123~127,仍在signed char的正数范围内,能正常触发ch > 'z'的判断,减26后得到'a'到'e',和你给出的输出结果完全吻合。
修复方案
提供两种可行的修复方式:
方案1:调整ch的变量类型
将ch的声明从char改为int或unsigned char,避免加13后发生溢出:
#include<stdio.h> int main() { char message[100]; int ch, i; // ch改成int类型 printf("Enter a message to encrypt: "); gets(message); for(i = 0; message[i] != '\0'; ++i){ ch = message[i]; if(ch >= 'a' && ch <= 'z'){ ch = ch + 13; if(ch > 'z'){ ch = ch - 26; } message[i] = ch; } else if(ch >= 'A' && ch <= 'Z'){ ch = ch + 13; if(ch > 'Z'){ ch = ch - 26; } message[i] = ch; } } printf("Encrypted message: %s", message); return 0; }
方案2:改用无溢出的计算逻辑
不需要修改变量类型,直接调整加密计算逻辑,从根源避免溢出,也不需要额外的范围判断:
// 小写字母加密逻辑 ch = 'a' + (ch - 'a' + 13) % 26; // 大写字母加密逻辑 ch = 'A' + (ch - 'A' + 13) % 26;
其他注意事项
- 代码中使用的
gets()函数已经被C标准废弃,存在严重的缓冲区溢出风险,建议替换为fgets(message, sizeof(message), stdin)使用。
内容的提问来源于stack exchange,提问作者Naher
相关产品推荐
相关产品推荐

