CS50 week2 Caesar作业check50报错output not valid ASCII text求助
错误原因排查
- 数组越界访问输出非ASCII字符:你的加密逻辑中两个
if判断是并列关系,没有互斥。当偏移后索引大于26时,第一个if输出了修正后的字符,第二个无额外判断的if仍会执行,直接访问lower_letters[a+total]/upper_letters[a+total]。大小写数组的合法索引只有0~25,当a+total超过25时属于数组越界访问,读取的内存值是不可控的非ASCII字符,这是output not valid ASCII text报错的核心原因。 - 大偏移处理逻辑失效:你仅对偏移超过26的情况做了一次减26处理,当密钥大于等于52时(比如测试用例中的65),减26后的值仍然大于25,还是会触发数组越界。
- 本地运行看似正常的原因:你本地环境中越界访问的内存地址刚好存储了可打印的ASCII值,所以肉眼看输出是对的,但check50的运行环境中该地址存储的是不可打印字符,因此判定失败。
解决方案
- 先对密钥取模26,将偏移量固定在0~25范围内,避免大密钥导致索引越界:
int total = atoi(argv[1]) % 26;
- 重构加密逻辑,使用互斥判断,去掉冗余的字符数组:直接利用ASCII码值做运算,不需要预存大小写字母数组,同时避免重复输出和越界:
for (int i = 0; i < strlen(word1); i++) { // 小写字母加密 if (islower(word1[i])) { int offset = word1[i] - 'a'; printf("%c", 'a' + (offset + total) % 26); } // 大写字母加密 else if (isupper(word1[i])) { int offset = word1[i] - 'A'; printf("%c", 'A' + (offset + total) % 26); } // 非字母字符直接原封不动输出 else { printf("%c", word1[i]); } }
- 可以删除原代码中预定义的
lower_letters、upper_letters数组,以及冗余的特殊字符判断逻辑,避免遗漏其他非字母字符的处理。
内容的提问来源于stack exchange,提问作者michael_fraser1201
相关产品推荐
相关产品推荐

