CS50替换密码程序测试报错:输出非有效ASCII文本求助
问题概述
完成CS50替换密码C代码编写与测试后,修复多个bug仍卡在两项测试:使用密钥yukfrnlbavmwzteogxhcipjsqd(全小写)和YUKFRNLBAVMWZteogxhcipjsqd(前半大写、后半小写)加密输入文本"This is CS50"时,均触发output not valid ASCII text错误。
常见错误原因及排查步骤
1. 非字母字符被错误替换
CS50的Substitution要求仅替换字母字符,空格、数字等非字母需原样输出。如果代码未做字符类型判断(比如未用isalpha()检查),直接对所有字符执行替换逻辑,会导致非字母字符(如ASCII 32的空格、ASCII 53的'5')被错误计算索引,访问密钥数组越界,读取到内存中随机的非ASCII数据。
排查代码:检查加密循环中是否有类似逻辑:
for (int i = 0; plaintext[i] != '\0'; i++) { if (isalpha(plaintext[i])) { // 执行字母替换逻辑 } else { // 直接保留原字符 ciphertext[i] = plaintext[i]; } }
如果缺失isalpha()判断,需补充。
2. 密钥大小写未统一处理
第二个密钥混合了大小写,若代码未将密钥统一转换为全大写或全小写,会导致映射索引混乱。比如,大写字母'A'对应索引0,小写字母'a'对应索引32,若直接用密钥中字符的ASCII值计算索引,会超出0-25的范围,生成非ASCII字符。
排查代码:检查密钥处理部分是否有统一大小写的逻辑:
// 将密钥统一转为大写示例 for (int i = 0; key[i] != '\0'; i++) { key[i] = toupper(key[i]); }
同时,加密时对输入字母的大小写判断要匹配:输入大写字母时,用0-25索引取密钥的大写字符;输入小写字母时,取密钥对应位置的字符后转小写。
3. 加密后字符超出可打印ASCII范围
可打印ASCII字符范围是32(空格)到126(~)。如果代码中映射逻辑错误,比如将字母索引计算错误(如负数、大于25的数),访问密钥数组越界,会读取到内存中超出该范围的字符。
排查代码:检查索引计算逻辑,比如:
// 正确的大写字母索引计算 if (isupper(plaintext[i])) { int index = plaintext[i] - 'A'; ciphertext[i] = toupper(key[index]); } // 正确的小写字母索引计算 else if (islower(plaintext[i])) { int index = plaintext[i] - 'a'; ciphertext[i] = tolower(key[index]); }
确保index始终在0-25之间,避免越界。
4. 密文字符串未添加终止符\0
如果ciphertext数组未在最后添加\0,输出时会读取数组后面的内存垃圾数据,其中可能包含非ASCII字符。
排查代码:加密循环结束后,务必添加:
ciphertext[len] = '\0'; // len为明文长度
错误日志示例(参考)
Testing with key: yukfrnlbavmwzteogxhcipjsqd Input: This is CS50 Error: output not valid ASCII text
内容的提问来源于stack exchange,提问作者Mustafa Legrand

