You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中使用双指针去除字符串中的空白字符?

用双指针法去除字符串空白的问题与修正

我尝试用接收双指针参数的方法去除字符串中的所有空白字符(例如输入 "a b c x")时遇到了问题,已经通过单指针和C++的string类解决了该问题,但出于好奇,想实现双指针版本的解法。

以下是我的尝试代码:

void remove_whitespace(char** s)
{
    char **rd; // "read" pointer
    char **wr; // "write" pointer

    rd = wr = s; // initially, both read and write pointers point to beginning of string

    while ( *rd != 0 ) // while not at end of string
    {
    while ( isspace( **rd ) ) // while rd points to a whitespace character
        rd++;                  // advance rd
    *wr++ = *rd++;           // copy *rd to *wr, advance both pointers
    }
    *wr = 0;                   // terminate the result

    printf("\nsquished: %s\n", s);
}

问题分析

这段代码的核心问题在于对char**类型指针的误用:

  • rd和wr被定义为char**,但实际我们需要操作的是字符串中的字符,应该用char*类型的指针来遍历字符,而非指针的指针。
  • 跳过空白的循环没有判断*rd是否已经是字符串结束符\0,如果输入全是空白字符,rd会越界访问到\0之后的内存,调用isspace(**rd)会触发未定义行为。
  • 打印时直接使用s(char**类型)作为printf的字符串参数,这是错误的,printf需要char*类型的字符串起始地址,应该用*s。

修正后的代码

如果坚持使用char**作为函数参数(虽然这里其实不需要修改原指针本身),正确的双指针实现如下:

#include <stdio.h>
#include <ctype.h>

void remove_whitespace(char** s)
{
    char* rd = *s; // 读取指针指向字符串起始位置
    char* wr = *s; // 写入指针指向字符串起始位置

    while (*rd != '\0') 
    {
        // 跳过所有空白字符,同时避免越界
        while (*rd != '\0' && isspace((unsigned char)*rd)) 
        {
            rd++;
        }
        // 未到字符串结尾时,复制字符并移动指针
        if (*rd != '\0') 
        {
            *wr++ = *rd++;
        }
    }
    // 添加字符串结束符
    *wr = '\0';

    printf("\nsquished: %s\n", *s);
}

// 测试示例
int main()
{
    char str[] = "a b  c    x";
    remove_whitespace(&str);
    return 0;
}

简化版本(更常用的写法)

如果不需要修改传入的指针本身,只需要修改字符串内容,函数参数可以简化为char*,代码更简洁:

#include <stdio.h>
#include <ctype.h>

void remove_whitespace(char* s)
{
    char* rd = s;
    char* wr = s;

    while (*rd != '\0')
    {
        while (*rd != '\0' && isspace((unsigned char)*rd))
        {
            rd++;
        }
        if (*rd != '\0')
        {
            *wr++ = *rd++;
        }
    }
    *wr = '\0';

    printf("\nsquished: %s\n", s);
}

int main()
{
    char str[] = "a b  c    x";
    remove_whitespace(str);
    return 0;
}

关键修正点

  • 将读写指针改为char*类型,正确遍历字符串中的字符。
  • 在跳过空白的循环中增加*rd != '\0'的判断,避免越界访问。
  • 复制字符前先判断是否到达字符串结尾,逻辑更严谨。
  • 打印时传入正确的字符串起始地址(*s或s,根据参数类型而定)。

内容的提问来源于stack exchange,提问作者Jonas Örnfelt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:32:51