scott
scott

Reputation: 53

How to remove spaces that are in a string sentence

I am trying to write a code to remove all the leading, trailing and middle of the sentence spaces but to keep only one space between the words.

For example if the input is

"    This    is my     string    "

the output should be

"This is my string"

So far I have come up with this:

#include <stdio.h>
void cascade(char str[], int i);
main()
{
    char str[100] = "    This    is my     string    ";
    int i = 0;
    while (str[i] != '\0') {
            if (str[i] == ' ' && str[i + 1] == ' ')
                    cascade(str, i);
            i++;
    }
    printf("%s\n", str);
}

void cascade(char str[], int i)
{
    while(str[i] != '\0') {
            str[i] = str[i + 1];
            i++;
    }
    str[i + 1] = '\0';
}

I would appreciate if anyone could come up with some ideas, Thank you.

Upvotes: 2

Views: 7753

Answers (5)

BLUEPIXY
BLUEPIXY

Reputation: 40145

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char** split(const char *str, const char *delimiter, size_t *len){
    char *text, *p, *first, **array;
    int c;
    char** ret;

    *len = 0;
    text=strdup(str);//strdup not standard
    if(text==NULL) return NULL;
    for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item
        if(c==0) first=p; //first token top

    ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL
    if(ret==NULL){
        free(text);
        return NULL;
    }
    //memmove?
    strcpy(text, str+(first-text));//skip until top token
    array=ret;
    for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){
        *array++=p;
    }
    *array=NULL;
    *len=c;
    return ret;
}

void free4split(char** sa){
    char **array=sa;

    if(sa!=NULL){
        free(array[0]);//for text
        free(sa);      //for array
    }
}

int main(void){
    char str[100] = "    This    is my     string    ";
    char **words;
    size_t len=0;
    int i;

    words = split(str, " \t", &len);
    *str = '\0';
    for(i = 0;i<len-1;++i){
        strcat(str, words[i]);
        strcat(str, " ");
    }
    strcat(str, words[i]);
    printf("\"%s\"\n", str);
    free4split(words);
    return 0;
}

Upvotes: 1

BLUEPIXY
BLUEPIXY

Reputation: 40145

#include <stdio.h>
#include <string.h>

char* trim(char str[]){
    char *p=str;
    char *token;
    if(str == NULL) return NULL;
    if(*str == '\0') return str;

    token=strtok(str, " \t");
    if(token == NULL){
        *str = '\0';
        return str;
    }
    while(NULL!=token){
        int len;
        len = strlen(token);
        if(p != token){
            memmove(p, token, len);
        }
        p += len;
        *p++ =' ';
        token = strtok(NULL, " \t");
    }
    p[-1]='\0';

    return str;
}

int main(){
    char str[100] = "    This    is my     string    ";
    printf("\"%s\"\n", trim(str));
    return 0;
}

Upvotes: 2

Mark Byers
Mark Byers

Reputation: 838076

Use two pointers. The first points at the next character to read, and the second points at the location to write.

If you read two spaces in a row, don't advance the write pointer.


Another approach you may want to consider is to use strtok with " " as a delimiter.

Upvotes: 5

biggdman
biggdman

Reputation: 2096

You could use a string tokenizer in the first instance, and use as a delimiter a whitespace(" "). For that purpose in C you use strtok.After that you parse the output of the strtok function, and for each element, if it contains more whitespaces character, you eliminate them. Also you put each corrected element in another array. Then, all you have to do is parse the new array and add a whitespace after every element. If you fancy this idea, I can provide a code draft for you.

Upvotes: 1

Brigand
Brigand

Reputation: 86220

You could have two arrays and two counters. Each iteration you always increase your first counter, but only increase your second when the character is not a space. A table of it would look like this.

  Char   In-Pos  Out-Pos

   ' '      0      0
   ' '      1      0
   ' '      2      0
   ' '      3      0
   'T'      4      0
   'h'      5      1
   'i'      6      2
   's'      7      3
   ' '      8      4
   ' '      9      5
   ' '     10      5
   ' '     11      5
   'i'     12      5
   's'     13      6
   ' '     14      7
   'm'     15      8
   'y'     16      9
   ' '     17     10
   ' '     18     11
   ' '     19     11
   ' '     20     11
   ' '     21     11
   's'     22     11
   't'     23     12
   'r'     24     13
   'i'     25     14
   'n'     26     15
   'g'     27     16
   ' '     28     17
   ' '     29     18
   ' '     30     18
   ' '     31     18

Upvotes: 2

Related Questions