繁体   English   中英

使用指针从字符串中删除空格

[英]Removing spaces from string using pointers

#include<stdio.h>

int main()
{
    unsigned int n=0;
    char str[100];
    char *ptr,*ptr1;    
    printf("Enter the string = ");
    gets(str);
    ptr = &str[0];
    while(*ptr!='\0')
    {
        n++;ptr++;
    }
    ptr=&str[0];
    while(*ptr!='\0')
    {
        if(*ptr==' ')
        {
            n--;
            for(ptr1=++ptr;*ptr1!='\0';ptr1++)
            {
                *ptr=*ptr1;
                 ptr++;
            }   
            ptr=&str[0];    
        }
        ptr++;
    }
    printf("Modified string = ");
    for(int i=0;i<n;i++)
    {
        printf("%c",str[i]);
    }
    return 0;
}

我知道从字符串中删除空格的另一种方法,但是我想使用指针来执行此操作,但是我无法弄清楚这段代码有什么问题?

我非常感谢您的帮助。

iharob确定了您的问题并给出了很好的解决方案,但我想向您展示一种略有不同的方法。

char *rd; // "read" pointer
char *wr; // "write" pointer

rd = wr = string; // initially, both read and write pointers point to
                  // beginning of the 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( "squished: %s\n", string );

使用测试字符串"This is a test" ,我们开始如下( \\0表示字符串终止符):

+----------------------- rd
|
V
This    is a   test\0
^
|
+----------------------- wr

前四个字符不是空格,因此我们只用相同的值覆盖这些字符并前进两个指针,从而得到

    +------------------- rd
    |
    V
This    is a   test\0
    ^
    |
    +------------------- wr

由于rd指向空格,因此我们将其继续前进,直到找到一个非空格字符:

        +--------------- rd
        |
        V
This    is a   test\0
    ^
    |
    +------------------- wr

然后,我们将该非空白字符写入wr指向的位置:

        +--------------- rd
        |
        V
Thisi   is a   test\0
    ^
    |
    +------------------- wr

继续进行直到找到下一个空格字符:

          +------------- rd
          |
          V
Thisis  is a   test\0
      ^
      |
      +----------------- wr

继续将rd前进到下一个非空白字符:

           +------------ rd
           |
           V
Thisis  is a   test\0
      ^
      |
      +----------------- wr

写到wr

           +------------ rd
           |
           V
Thisisa is a   test\0
      ^
      |
      +----------------- wr

泡沫,冲洗,重复:

                   +---- rd
                   |
                   V
Thisisatesta   test\0
           ^
           |
           +------------ wr

rd现在指向字符串的末尾。 我们退出主循环,并在wr写入0以终止字符串:

                   +---- rd
                   |
                   V
Thisisatest\0  test\0
           ^
           |
           +------------ wr

我更喜欢这种解决方案,因为每个字符只能移到其最终位置一次。 您可以结束在字符串开头不需要的字符覆盖,但是我认为这是一个合理的权衡。

编辑

Chux的版本有点过时了,而且绝对是C的精神:

do
{
  while ( isspace( *rd ) )  // while rd points to whitespace
    rd++;                   // advance rd
}
while ( (*wr++ = *rd++) );  // copy rd to wr, advance pointers until
                            // we see the string terminator

同样,每个角色只能移到其最终位置一次。

有两个问题

  1. 在这条线

     for(ptr1 = ++ptr ; *ptr1 != '\\0' ; ptr1++) 

    因为您增加了ptr ,因此ptr1ptr指向同一位置,所以您实际上是将字符复制到同一位置,而ptr1应该指向ptr + 1ptr不应被修改。

  2. 您还可以所有字符从右移到左一处,然后从字符串的开头开始

     ptr = &str[0]; 

    在移动字符的循环之后,您应该保存先前的位置并指向它,这样会更有效率。

我们已经解决了您的代码,以下代码可以正常工作

#include <stdio.h>
#include <math.h>

int main()
{
    char  str[100];
    char *ptr;    

    printf("Enter the string = ");
    fgets(str, sizeof(str), stdin);

    ptr = str;
    while (*ptr != '\0')
    {
        char *save;         
        save = ptr;
        if (*ptr == ' ')
        {
            char *next;
            for (next = ptr + 1 ; *next != '\0' ; next++, ptr++)
                *ptr = *next;
            ptr = save;
        }
        ptr++;
    }    
    printf("Modified string = %s\n", str);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM