C语言解密字符串元音计数异常:'o'无法触发counter自增问题排查
C语言解密问题:元音统计异常('o'无法被计数)的原因及修复
核心问题根源
你代码里最致命的错误是在循环中直接修改了原始数组original的内容。当计算出的a > 122(也就是超过小写字母'z'的ASCII值)时,你执行了original[i] -= 26,这会永久篡改原数组的字符值,导致后续所有循环的移位计算全部出错——包括原本应该被识别为'o'的情况,因为原字符已经被改得面目全非,计算出的a自然不是预期的元音了。
具体问题拆解
原数组被篡改,后续计算全错
第一次循环j=0时可能还正常,但随着j增大,部分字符移位后会超出'z',这时候你修改了original[i],之后的循环再用这个被改过的字符计算移位,得到的结果完全不是你想要的解密字符,就算移位后本该是'o',最终算出的a也不对,counter++自然不会触发。移位逻辑本身错误
你当前处理循环移位的方式完全不对,凯撒密码的正确移位应该通过模运算实现,而不是修改原数组。正确的移位计算应该是:char a = ((original[i] - 'a') + j) % 26 + 'a';这种方式既不会改动原数组,还能自动处理超出'z'的情况(比如'z'+1会自动转回'a')。
修复后的完整代码
#include <stdio.h> int main(void) { // 用字符串字面量初始化更规范,自动补全结束符'\0' char original[15] = "tflekvidvrjlivi"; printf("암호화된 문자열 : %s\n", original); printf("원본 가능 문자열 \n\n"); for (int j = 0; j < 26; j++) { int counter = 0; printf("移位%d: ", j); // 用字符串结束符判断循环终点,避免硬编码长度 for (int i = 0; original[i] != '\0'; i++) { // 正确计算移位后的字符,不修改原数组 char a = ((original[i] - 'a') + j) % 26 + 'a'; // 统计元音 if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') { counter++; } printf("%c", a); } printf(" 元音数量: %d\n", counter); } return 0; }
额外注意点
- 原代码里用
NULL作为字符串结束符是错误的,字符串结束符应该是'\0',用字符串字面量初始化可以避免这个问题。 - 循环判断
i < 14属于硬编码,改用original[i] != '\0'更灵活,也更符合C语言字符串的处理习惯。
内容的提问来源于stack exchange,提问作者Pool_one
相关产品推荐
相关产品推荐

