2
#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;
}

I know the other way of removing spaces from string but i want to do this using pointers but i cant get what is wrong with this code?

I really appreciate some little help.

4
  • 1
    This ptr=&str[0]; is the same as ptr = str;. Also, DO NOT USE gets(). Commented Jun 24, 2015 at 20:12
  • I know that, it just keep things simple Commented Jun 24, 2015 at 20:14
  • do not use gets(), can buffer overflow. Commented Jun 24, 2015 at 20:15
  • fgets(str, sizeof(str), stdin) looks very simple to me., and ptr = str; is certainly simpler. Commented Jun 24, 2015 at 20:18

2 Answers 2

5

iharob identified your problem and gave a good solution, but I'd like to show you a slightly different approach.

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 );

Walking through this with the test string "This is a test", we start out as follows (\0 represents the string terminator):

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

The first four characters aren't whitespace, so we just overwrite those characters with the same values and advance the two pointers, giving us

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

Since rd is pointing to whitespace, we continue to advance it until we find a non-whitespace character:

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

We then write that non-whitespace character to the location pointed to by wr:

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

Keep this up until we find the next whitespace character:

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

Continue to advance rd to the next non-whitespace character:

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

Write it to wr:

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

Lather, rinse, repeat:

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

rd now points to the end of the string. We exit the main loop and write a 0 to wr to terminate the string:

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

I prefer this solution since each character only gets shifted once to its final location. You wind up overwriting characters that you don't need to at the beginning of the string, but I think that's a reasonable tradeoff.

Edit

Chux's version is a bit slicker, and definitely more in the spirit of 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

Again, each character only gets shifted once to its final location.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice - I was hoping to see an O(n) rather than O(n*n) solution.. Minor: code could use do { while ( isspace( *rd ) ) rd++; } while ((*wr++ = *rd++) != '\0');, yet your code looks easier to understand.
@chux - yeah, that's definitely slicker and more in the spirit of C than my version. I could pretend I was writing for clarity, but in truth I just didn't spend too much time thinking about it.
Your original version will continue past the null terminator if the initial string ends with a space, because rd will advance up to the null terminator while skipping spaces in the inner while loop, then past it on the following line.
1

There are two problems

  1. In this line

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

    because you increment ptr and hence both ptr1 and ptr point to the same place after that, so you are effectively copying the characters to the same place, instead ptr1 should point to ptr + 1 while ptr should not be modified.

  2. You also start at the beggining of the string after "moving" all the charaters from the right one place to the left, here

    ptr = &str[0];
    

    right after the loop that moves the characters, you should save the previous position and point to it instead, that would be more efficient.

I've fixed your code and the following code works

#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;
}

1 Comment

yeah u r right about first condtion in for loop. thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.