Home > OS >  Is there an easy way to remove specific chars from a char*?
Is there an easy way to remove specific chars from a char*?

Time:03-10

char * deleteChars = "\"\'.“”‘’?:;-,—*($%)! \t\n\x0A\r"

I have this and i'm trying to remove any of these from a given char*. I'm not sure how I would go about comparing a char* to it.

For example if the char* is equal to "hello," how would I go about removing that comma with my deleteChars?

So far I have

void removeChar(char*p, char*delim){
char*holder = p;
while(*p){
    if(!(*p==*delim  )){
        *holder  =*p;
        p  ;
    }
}
*holder = '\0';

CodePudding user response:

A simple one-by-one approach:

You can use strchr to decide if the character is present in the deletion set. You then assign back into the buffer at the next unassigned position, only if not a filtered character.

It might be easier to understand this using two indices, instead of using pointer arithmetic.

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

void remove_characters(char *from, const char *set)
{
    size_t i = 0, j = 0;

    while (from[i]) {
        if (!strchr(set, from[i]))
            from[j  ] = from[i];
        i  ;
    }

    from[j] = 0;
}

int main(void) {
    const char *del = "\"\'.“”‘’?:;-,—*($%)! \t\n\x0A\r";
    char buf[] = "hello, world!";

    remove_characters(buf, del);

    puts(buf);
}

stdout:

hello world

CodePudding user response:

If you've several delimiters/characters to ignore, it's better to use a look-up table.

void remove_chars (char* str, const char* delims)
{
    if (!str || !delims) return;

    char* ans = str;
    int dlt[256] = {0};
    while (*delims)
        dlt[(unsigned char)*delims  ] = 1;

    while (*str) {
        if (dlt[(unsigned char)*str])
              str; // skip it
        else //if (str != ans)
            *ans   = *str  ;
    }
    *ans = '\0';
}

CodePudding user response:

it is better way - return the string without needless characters

#include <string.h>
char * remove_chars(char * str, const char * delim) {
    for ( char * p = strpbrk(str, delim); p; p = strpbrk(p, delim) )
        memmove(p, p   1, strlen(p));
    return str;
}

CodePudding user response:

You could do a double loop, but depending on what you want to treat, it might not be ideal. And since you are FOR SURE shrinking the string you don't need to malloc (provided it was already malloced). I'd initialize a table like this.

#include <string.h>
...
char del[256];
memset(del, 0, 256 * sizeof(char));
for (int i = 0; deleteChars[i]; i  ) del[deleteChars[i]] = 1;

Then in a function:

void delChars(char *del, char *string) {
  int i, offset;
  for (i = 0, offset = 0; string[i]; i  ) {
    string[i - offset] = string[i];
    if (del[string[i]]) offset  ;
  }
  string[i - offset] = 0;
}

This will not work on string litterals (that you initilize with char* x = "") though cause you'd endup writing in program memory, and probably segfault. I'm sure you can tweak it if that's your need. (Just do something like char *newString = malloc(strlen(string)); newString[i - offset] = string[i])

  •  Tags:  
  • c
  • Related