简体   繁体   中英

Remove spaces from string doesn't return anything

This code removes spaces from a string.

char *RemoveSpaces(char *source)
{  
    char* i = source;
    char* j = source;
    while(*j != '\0')
    {
        *i = *j++;
        if(*i != ' ')
            i++;
    }
    *i = 0;
    return i;
}

But when I use printf it doesn't return anything.

printf("%s", RemoveSpaces("HELLO WORLD!!! COME ONE\r"));
*i = 0;
return i;   // wrong pointer returned

is wrong. It returns a pointer to the string termination (ie a pointer to the 0). Therefore it prints nothing.

Try:

*i = 0;            // or *i = '\0';
return source;     // correct pointer returned

Further, modifying a string literal is not allowed. Instead do:

char str[] = "HELLO WORLD!!! COME ONE\r";
printf("%s", RemoveSpaces(str));

A slight adjustment to your space removal logic may help things make more sense. Instead of setting

    *i = *j++;
    if(*i != ' ')
        i++;

before you test whether *i != ' ' , you may find it makes more sense to test first and then assign (where p is your i and ep (end pointer) is your j ), eg

    while (*ep) {           /* iterate ep from beginning to end of src */
        if (*ep != ' ')     /* if its not a space */
            *p++ = *ep;     /* set begin pointer to char at end ptr, advance */
        ep++;               /* advance to next char */
    }
    *p = 0;                 /* nul-terminate src at p */

In that sense, you only assign and advance the initial pointer if the current character is not a space.

In your example and here, you are modifying the content of source in place, your 'i' and 'j' pointers are used for iterating over the characters in source , so when you are done with the iterations, you return source (or source can be used back in the caller without the return as you are modifying the contents of source in-place.

Putting those pieces together, you could do something similar like the following that will take the string to remove spaces from as the first argument to your code (or use "HELLO WORLD!!! COME ONE\\n" by default if no argument is given), eg

#include <stdio.h>

char *rmspaces (char *src)
{
    char *p = src,          /* pointer to beginning of src */
        *ep = src;          /* pointer to iterate to the end of src */

    while (*ep) {           /* iterate ep from beginning to end of src */
        if (*ep != ' ')     /* if its not a space */
            *p++ = *ep;     /* set begin pointer to char at end ptr, advance */
        ep++;               /* advance to next char */
    }
    *p = 0;                 /* nul-terminate src at p */

    return src;
}

int main (int argc, char **argv) {

    char *s = argc > 1 ? argv[1] : (char[]){"HELLO WORLD!!! COME ONE\n"};
    printf ("%s", rmspaces (s));

    return 0;
}

( Note: , your editing in-place is fine, but source (or src ) in my case must be modifiable, meaning you cannot pass a string-literal as source (which would likely SegFault). Above a compound-literal is used in the default case to insure the test past is a modifiable character array)

Example Use/Output

$ ./bin/rmspaces
HELLOWORLD!!!COMEONE

Look things over and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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