CS50x Caesar密码程序加密异常:特定字符输出乱码求助
CS50x Caesar密码程序乱码问题排查
我正在完成CS50x课程Problem Set 2的Caesar密码实现任务,需编写加密消息的程序caesar.c。当输入明文"world, say hello"、密钥为12时,程序输出不符合预期,字符w和y的位置出现问号乱码。以下是我的代码:
#include<stdio.h> #include<cs50.h> #include<ctype.h> #include<string.h> int main(int argc,string argv[]){ if(argc==2) //to make sure there's only one string after ./caesar { int digit=0,key=0; for(int i=0,n=strlen(argv[1]);i<n;i++) { if(argv[1][i]>='0' && argv[1][i]<='9') { digit= argv[1][i]-'0'; key=key*10+digit; } else{ printf("Usage: ./caesar key\n"); return 1; } } string text=get_string("plainttext: "); printf("ciphertext: "); key=key%26; for(int i=0,n=strlen(text);i<n;i++){ if(islower(text[i])) { text[i]=text[i]+key; if(text[i]>'Z') { text[i]=text[i]-26; } printf("%c",(char)text[i]); } else if(isupper(text[i])) { text[i]=text[i]+key; if(text[i]>'Z') { text[i]=text[i]-26; } printf("%c",(char)text[i]); } else printf("%c",(char)text[i]); } printf("\n %i",key); return 0; } else{ printf("Usage: ./caesar key\n"); return 1; } }
问题原因分析
- 小写字母溢出判断逻辑错误:处理小写字母时,代码用
text[i] > 'Z'作为回绕判断条件,但'Z'是大写字母的ASCII值(90),而小写字母的ASCII值本身就大于90,导致所有小写字母加密都会触发减26操作。更严重的是,当text[i]+key超过有符号char的最大值127时,会产生溢出变成负数,打印时就会出现问号乱码。比如小写w(ASCII 119)加12后是131,超出有符号char范围,数值异常导致乱码。 - 直接字符相加易触发溢出:直接对char类型的字符做加法运算,一旦结果超出char的取值范围,就会出现未定义的数值异常。
修正方案
采用索引转换法彻底避免溢出问题:先将字母转换为0-25的索引,计算加密后的索引后再转回对应字符:
- 小写字母:
(text[i] - 'a' + key) % 26 + 'a' - 大写字母:
(text[i] - 'A' + key) % 26 + 'A'
修正后的核心代码片段
for(int i=0,n=strlen(text);i<n;i++){ if(islower(text[i])) { int idx = text[i] - 'a'; idx = (idx + key) % 26; printf("%c", idx + 'a'); } else if(isupper(text[i])) { int idx = text[i] - 'A'; idx = (idx + key) % 26; printf("%c", idx + 'A'); } else printf("%c", text[i]); }
修正后,输入明文"world, say hello"、密钥12时,正确输出应为"iqdkg, amk tqxxa",不会出现乱码。
内容的提问来源于stack exchange,提问作者persiandrunkard
相关产品推荐
相关产品推荐

