[c] Removing Spaces from a String in C?

What is the easiest and most efficient way to remove spaces from a string in C?

This question is related to c string spaces

The answer is


#include <ctype>

char * remove_spaces(char * source, char * target)
{
     while(*source++ && *target)
     {
        if (!isspace(*source)) 
             *target++ = *source;
     }
     return target;
}

Notes;

  • This doesn't handle Unicode.

Here is the simplest thing i could think of. Note that this program uses second command line argument (argv[1]) as a line to delete whitespaces from.

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

/*The function itself with debug printing to help you trace through it.*/

char* trim(const char* str)
{
    char* res = malloc(sizeof(str) + 1);
    char* copy = malloc(sizeof(str) + 1);
    copy = strncpy(copy, str, strlen(str) + 1);
    int index = 0;

    for (int i = 0; i < strlen(copy) + 1; i++) {
        if (copy[i] != ' ')
        {
            res[index] = copy[i];
            index++;
        }
        printf("End of iteration %d\n", i);
        printf("Here is the initial line: %s\n", copy);
        printf("Here is the resulting line: %s\n", res);
        printf("\n");
    }
    return res;
}

int main(int argc, char* argv[])
{
    //trim function test

    const char* line = argv[1];
    printf("Here is the line: %s\n", line);

    char* res = malloc(sizeof(line) + 1);
    res = trim(line);

    printf("\nAnd here is the formatted line: %s\n", res);

    return 0;
}

I assume the C string is in a fixed memory, so if you replace spaces you have to shift all characters.

The easiest seems to be to create new string and iterate over the original one and copy only non space characters.


Here's a very compact, but entirely correct version:

do while(isspace(*s)) s++; while(*d++ = *s++);

And here, just for my amusement, are code-golfed versions that aren't entirely correct, and get commenters upset.

If you can risk some undefined behavior, and never have empty strings, you can get rid of the body:

while(*(d+=!isspace(*s++)) = *s);

Heck, if by space you mean just space character:

while(*(d+=*s++!=' ')=*s);

Don't use that in production :)


Code taken from zString library

/* search for character 's' */
int zstring_search_chr(char *token,char s){
        if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}

char *zstring_remove_chr(char *str,const char *bad) {
    char *src = str , *dst = str;

    /* validate input */
    if (!(str && bad))
        return NULL;

    while(*src)
        if(zstring_search_chr(bad,*src))
            src++;
        else
            *dst++ = *src++;  /* assign first, then incement */

    *dst='\0';
    return str;
}

Code example

  Exmaple Usage
      char s[]="this is a trial string to test the function.";
      char *d=" .";
      printf("%s\n",zstring_remove_chr(s,d));

  Example Output
      thisisatrialstringtotestthefunction

Have a llok at the zString code, you may find it useful https://github.com/fnoyanisi/zString


As we can see from the answers posted, this is surprisingly not a trivial task. When faced with a task like this, it would seem that many programmers choose to throw common sense out the window, in order to produce the most obscure snippet they possibly can come up with.

Things to consider:

  • You will want to make a copy of the string, with spaces removed. Modifying the passed string is bad practice, it may be a string literal. Also, there are sometimes benefits of treating strings as immutable objects.
  • You cannot assume that the source string is not empty. It may contain nothing but a single null termination character.
  • The destination buffer can contain any uninitialized garbage when the function is called. Checking it for null termination doesn't make any sense.
  • Source code documentation should state that the destination buffer needs to be large enough to contain the trimmed string. Easiest way to do so is to make it as large as the untrimmed string.
  • The destination buffer needs to hold a null terminated string with no spaces when the function is done.
  • Consider if you wish to remove all white space characters or just spaces ' '.
  • C programming isn't a competition over who can squeeze in as many operators on a single line as possible. It is rather the opposite, a good C program contains readable code (always the single-most important quality) without sacrificing program efficiency (somewhat important).
  • For this reason, you get no bonus points for hiding the insertion of null termination of the destination string, by letting it be part of the copying code. Instead, make the null termination insertion explicit, to show that you haven't just managed to get it right by accident.

What I would do:

void remove_spaces (char* restrict str_trimmed, const char* restrict str_untrimmed)
{
  while (*str_untrimmed != '\0')
  {
    if(!isspace(*str_untrimmed))
    {
      *str_trimmed = *str_untrimmed;
      str_trimmed++;
    }
    str_untrimmed++;
  }
  *str_trimmed = '\0';
}

In this code, the source string "str_untrimmed" is left untouched, which is guaranteed by using proper const correctness. It does not crash if the source string contains nothing but a null termination. It always null terminates the destination string.

Memory allocation is left to the caller. The algorithm should only focus on doing its intended work. It removes all white spaces.

There are no subtle tricks in the code. It does not try to squeeze in as many operators as possible on a single line. It will make a very poor candidate for the IOCCC. Yet it will yield pretty much the same machine code as the more obscure one-liner versions.

When copying something, you can however optimize a bit by declaring both pointers as restrict, which is a contract between the programmer and the compiler, where the programmer guarantees that the destination and source are not the same address (or rather, that the data they point to are only accessed through that very pointer and not through some other pointer). This allows more efficient optimization, since the compiler can then copy straight from source to destination without temporary memory in between.


#include<stdio.h>
#include<string.h>
main()
{
  int i=0,n;
  int j=0;
  char str[]="        Nar ayan singh              ";
  char *ptr,*ptr1;
  printf("sizeof str:%ld\n",strlen(str));
  while(str[i]==' ')
   {
     memcpy (str,str+1,strlen(str)+1);
   }
  printf("sizeof str:%ld\n",strlen(str));
  n=strlen(str);
  while(str[n]==' ' || str[n]=='\0')
    n--;
  str[n+1]='\0';
  printf("str:%s ",str);
  printf("sizeof str:%ld\n",strlen(str));
}

The easiest and most efficient way to remove spaces from a string is to simply remove the spaces from the string literal. For example, use your editor to 'find and replace' "hello world" with "helloworld", and presto!

Okay, I know that's not what you meant. Not all strings come from string literals, right? Supposing this string you want spaces removed from doesn't come from a string literal, we need to consider the source and destination of your string... We need to consider your entire algorithm, what actual problem you're trying to solve, in order to suggest the simplest and most optimal methods.

Perhaps your string comes from a file (e.g. stdin) and is bound to be written to another file (e.g. stdout). If that's the case, I would question why it ever needs to become a string in the first place. Just treat it as though it's a stream of characters, discarding the spaces as you come across them...

#include <stdio.h>

int main(void) {
    for (;;) {
        int c = getchar();
        if (c == EOF) { break;    }
        if (c == ' ') { continue; }
        putchar(c);
    }
}

By eliminating the need for storage of a string, not only does the entire program become much, much shorter, but theoretically also much more efficient.


That's the easiest I could think of (TESTED) and it works!!

char message[50];
fgets(message, 50, stdin);
for( i = 0, j = 0; i < strlen(message); i++){
        message[i-j] = message[i];
        if(message[i] == ' ')
            j++;
}
message[i] = '\0';

if you are still interested, this function removes spaces from the beginning of the string, and I just had it working in my code:

void removeSpaces(char *str1)  
{
    char *str2; 
    str2=str1;  
    while (*str2==' ') str2++;  
    if (str2!=str1) memmove(str1,str2,strlen(str2)+1);  
}

I came across a variation to this question where you need to reduce multiply spaces into one space "represent" the spaces.

This is my solution:

char str[] = "Put Your string Here.....";

int copyFrom = 0, copyTo = 0;

printf("Start String %s\n", str);

while (str[copyTo] != 0) {
    if (str[copyFrom] == ' ') {
        str[copyTo] = str[copyFrom];
        copyFrom++;
        copyTo++;

        while ((str[copyFrom] == ' ') && (str[copyFrom] !='\0')) {
            copyFrom++;
        }
    }

    str[copyTo] = str[copyFrom];

    if (str[copyTo] != '\0') {
        copyFrom++;
        copyTo++;
    }
}

printf("Final String %s\n", str);

Hope it helps :-)


In C, you can replace some strings in-place, for example a string returned by strdup():

char *str = strdup(" a b c ");

char *write = str, *read = str;
do {
   if (*read != ' ')
       *write++ = *read;
} while (*read++);

printf("%s\n", str);

Other strings are read-only, for example those declared in-code. You'd have to copy those to a newly allocated area of memory and fill the copy by skipping the spaces:

char *oldstr = " a b c ";

char *newstr = malloc(strlen(oldstr)+1);
char *np = newstr, *op = oldstr;
do {
   if (*op != ' ')
       *np++ = *op;
} while (*op++);

printf("%s\n", newstr);

You can see why people invented other languages ;)


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to spaces

Visual Studio Code - Convert spaces to tabs Removing spaces from a variable input using PowerShell 4.0 Sublime Text 3, convert spaces to tabs Read input numbers separated by spaces How do I convert a list into a string with spaces in Python? How to copy directories with spaces in the name How can I convert tabs to spaces in every file of a directory? How can I convert spaces to tabs in Vim or Linux? Adding whitespace in Java Converting a sentence string to a string array of words in Java