Search code examples
cstringignore-duplicates

filter continuous duplicate chars in a string


Is there any problems in my code ,or to be improved ?

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

char * filterdupchar(char* s,int n){
    char *tmp2 = s ;
    char *tmp =(char*)malloc(n*sizeof(char));
    for(int j=0;j<n/2;j++){
        int i=0,p=0;
        while(i<n){
            *(tmp+p) = s[i];
            if(s[i]==s[i+1])
                i = i+2;
            else
                i++;
            p++;
        }
    s = tmp;
   }
    s = tmp2;
    return tmp;
}
int main(){
     char * str= "bbaaan";
     printf("%s",str);
     printf("\n");
     char * strnew;
     strnew = filterdupchar(str,6);
     printf("%s",strnew);
     return 1;
}

The result should be "ban", but it is appended to something disordered character. In my func , is it necessary to give tmp2 to s, and do i need to free sth.?


Solution

  • changes

    • only need single loop and lag character to do the filter ( above was unnecessarily complicated )
    • need to allocate number of characters + 1 ( for nullchar ) for tmp..
    • malloc cast not required
    • added nullchar to end of tmp
    • main should return 0 on success. otherwise processes consuming this will get confused
    • free strnew is required..
    • use valgrind if you have any memory doubts
    • consecutive calls to print are redundant..

    code

    #include <stdio.h>
    #include <stdlib.h>
    
    char * filterdupchar(char* s,int n)
    {
      int from,to; char last;
      char *tmp = malloc((n+1)*sizeof(char));
      from = to = 0;
      last = 0;
      for(from = 0; from < n; from++)
      {
        if(s[from] != last)
        {
          tmp[to] = s[from];
          to++;
        }
        last = s[from];
      }
      tmp[to] = '\0';
      return tmp;
    }
    int main()
    {
      char * str= "bbaaan";
      printf("%s\n",str);
      char * strnew;
      strnew = filterdupchar(str,6);
      printf("%s\n",strnew);
      free(strnew);
      return 0;
    }
    

    output

    $ valgrind ./test
    ==11346== Memcheck, a memory error detector
    ==11346== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
    ==11346== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
    ==11346== Command: ./test
    ==11346== 
    bbaaan
    ban
    ==11346== 
    ==11346== HEAP SUMMARY:
    ==11346==     in use at exit: 0 bytes in 0 blocks
    ==11346==   total heap usage: 1 allocs, 1 frees, 7 bytes allocated
    ==11346== 
    ==11346== All heap blocks were freed -- no leaks are possible
    ==11346== 
    ==11346== For counts of detected and suppressed errors, rerun with: -v
    

    notes

    always use a memory checker ( like valgrind ) to test for memory leaks