C语言连续字母替换逻辑bug排查:多段重复字符与数字截断问题
问题排查与代码修正
你的代码存在几个关键问题,导致复杂输入下出现错误,以下是具体分析和修复方案:
核心问题分析
strcpy处理重叠内存的未定义行为
当替换长度为3的连续字母序列(如abc)时,strcpy(str + start +3, str + end +1)的源地址和目标地址完全相同(因为end = start+2,end+1 = start+3)。C标准规定,strcpy处理重叠内存区域时行为未定义,这会导致后续字符处理出现随机错误,比如你遇到的第二个abc变成bc的情况。指针调整逻辑脆弱
原代码通过pointer -= counter -2调整指针,这种基于递增次数的计算容易在多次替换后出现偏移,导致后续序列的起始位置判断错误。缓冲区容量不足
char str[80]的缓冲区只能容纳79个有效字符,长输入会被截断,引发数字丢失、序列处理不完整等问题。isalpha参数类型错误
isalpha的参数应为unsigned char,若传入负数(如某些扩展ASCII字符)会触发未定义行为。
修正后的代码
#include <stdio.h> #include <string.h> #include <ctype.h> void replace(char str[], int start, int end, int *len) { str[start + 1] = '-'; str[start + 2] = str[end]; // 使用memmove安全处理内存重叠 int move_bytes = *len - end; memmove(str + start + 3, str + end + 1, move_bytes); // 更新字符串长度 *len -= (end - start - 2); } void search(char str[]) { int len = strlen(str); int i = 0; while (i < len) { // 跳过非字母字符 if (!isalpha((unsigned char)str[i])) { i++; continue; } int start = i; // 查找连续递增的字母序列(大小写区分,数字不处理) while (i + 1 < len && isalpha((unsigned char)str[i+1]) && str[i] + 1 == str[i+1]) { i++; } int end = i; // 仅当序列长度≥3时执行替换 if (end - start + 1 >= 3) { replace(str, start, end, &len); // 替换后从尾字母的下一位继续处理 i = start + 2; } else { i++; } } } int main() { // 增大缓冲区避免长输入截断 char str[1024]; while (fgets(str, sizeof str, stdin) != NULL) { // 移除fgets读取的换行符 str[strcspn(str, "\n")] = '\0'; search(str); printf("%s\n", str); } return 0; }
关键修复点说明
- memmove替代strcpy:memmove可以安全处理内存重叠的情况,确保替换操作后字符串数据正确。
- 跟踪字符串长度:在替换后更新字符串长度,避免循环处理已被覆盖的无效数据。
- 简化指针逻辑:直接定位到替换后的尾字母位置,后续从该位置继续遍历,避免指针偏移错误。
- 增大缓冲区:将缓冲区改为1024字节,足以处理大多数常规输入。
- 修正isalpha参数:将字符转换为
unsigned char后传入isalpha,避免未定义行为。
测试你提供的输入:
输入:abcdef12345ABCDxyz abc abc abc
输出:a-f12345A-Dx-z a-c a-c a-c,与期望一致。
长输入场景下也不会出现数字截断或序列处理错误的问题。
内容的提问来源于stack exchange,提问作者Tim Asher
相关产品推荐
相关产品推荐

