C语言函数内无法修改入参指针地址,如何实现字符串多余空格去除?
问题解决:原地去除字符串多余空格(仅保留单个空格)
原代码的核心问题
你遇到的两个关键问题:
- 函数内的
newstr是栈上局部变量,函数执行完毕后这块内存会被回收,外部访问会触发未定义行为; - C语言参数是值传递,你在函数里修改
s = &newstr只是改变了函数内部的指针副本,完全不会影响外部传入的指针指向——这也是为什么二级指针才能修改外部指针的原因,但既然作业不让改参数类型,原地修改原字符串是最优解。
另外原代码里的else分支完全多余,前面已经覆盖了*s是空格和非空格的所有情况。
原地修改的实现思路
不需要额外创建新字符串,利用双指针在原字符串上直接操作:
- 用
dp指针遍历原字符串,负责读取字符; - 用
p指针记录写入位置,负责把有效字符写回原字符串; - 先跳过开头的连续空格,避免结果开头留空格;
- 遍历过程中过滤连续空格,只保留单个;
- 最后处理末尾可能遗留的空格,再加上字符串结束符。
最终可行代码
void str_trim(char *s) { char *p = s, *dp = s; // 跳过开头的所有连续空格 while (*dp == ' ') dp++; // 遍历处理剩余字符 while (*dp) { // 如果当前是空格且前一个也是空格,跳过当前空格 if (*dp == ' ' && *(dp - 1) == ' ') { dp++; } else { // 复制字符到目标位置,同时移动两个指针 *p++ = *dp++; } } // 处理末尾可能遗留的单个空格 if (p > s && *(p - 1) == ' ') { p--; } // 添加字符串结束符,截断原字符串 *p = '\0'; }
代码说明
- 开头空格处理:第一个循环直接跳过所有开头的空格,确保结果字符串不会以空格开头;
- 连续空格过滤:遍历过程中,只有当前空格的前一个字符不是空格时,才会保留这个空格,避免连续空格出现;
- 末尾空格处理:循环结束后如果最后一个字符是空格,回退指针去掉它,保证结果不会以空格结尾;
- 原地修改:所有操作都在原字符串的内存空间完成,不需要额外分配内存,也不会有局部变量销毁的问题,同时完全符合参数类型不变的要求。
内容的提问来源于stack exchange,提问作者user1497350
相关产品推荐
相关产品推荐

