在线编译器 C

#include <stdio.h> #include <string.h> void result(char c[]) { int i = 0; int counter = 1; while (c[i] != '\0') { if (c[i] == c[i + 1]) { counter++; } else if (c[i] != c[i + 1] || c[i + 1] == '\0') { printf("%c%d", c[i], counter); counter = 1; } i++; } } int main() { char a[1001]; scanf("%[^\n]", a); result(a); return 0; }
这段代码的功能是读取一行字符串,然后对其中连续相同的字符进行压缩输出,例如输入 "aaabbb" 会输出 "a3b3"。代码整体思路正确,但存在一个边界条件问题。

- 当字符串遍历到最后一个字符时,`c[i+1]` 是字符串结束符 `\0`,此时 `c[i] != c[i+1]` 条件成立,会触发输出。但注意 `else if` 中的 `c[i+1] == '\0'` 判断是多余的,因为 `c[i] != c[i+1]` 已经包含了这种情况。不过这不是主要问题。

- 主要问题在于:当连续字符出现在字符串末尾时,比如输入 "abbb",循环处理到最后一个 'b' 时,`c[i] == c[i+1]` 不成立(因为 `c[i+1]` 是 `\0`),会进入 `else if` 分支输出 "b3"。但此时 `counter` 的值是3,而实际上最后一个 'b' 的计数在循环中只累加到了3,输出是正确的。然而,如果输入是单个字符如 "a",循环中 `c[0]` 是 'a',`c[1]` 是 `\0`,`c[0] != c[1]` 成立,输出 "a1",看起来也正确。那么问题在哪里呢?

- 仔细检查:当连续字符出现在字符串中间时,比如 "aab",处理到第二个 'a' 时,`c[i] == c[i+1]` 不成立(因为下一个是 'b'),会输出 "a2",然后 `counter` 重置为1。接着处理 'b' 时,`c[i] == c[i+1]` 不成立(因为下一个是 `\0`),输出 "b1"。这看起来也正确。

- 实际上,这段代码在大多数情况下能正常工作,但有一个隐藏问题:当字符串以连续相同字符结尾时,比如 "aa",循环过程:i=0,c[0]=='a', c[1]=='a',相等,counter=2;i=1,c[1]=='a', c[2]=='\0',不相等,进入 else if,输出 "a2"。