MightyPork

str_replace good?

Mar 25th, 2014
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.53 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5.  
  6. char* str_replace(const char *src, const char *from, const char *to) {
  7.    
  8.     if(src == NULL || from == NULL || to == NULL) return NULL;
  9.    
  10.     // helper pointers
  11.     const char * sp; // src pointer
  12.     const char * mp; // match pointer
  13.     char * dp; // dest pointer (for writing)
  14.    
  15.    
  16.     // lengths
  17.     size_t from_len = strlen(from);
  18.     size_t to_len = strlen(to);
  19.     size_t src_len = strlen(src);
  20.    
  21.     // count matches
  22.     size_t count = 0;
  23.     sp = src;
  24.     while(1) {
  25.         mp = strstr(sp, from); // find next match
  26.         if(mp == NULL) break; // end of matches
  27.         count++;
  28.         sp = mp + from_len; // advance past match
  29.     }
  30.    
  31.     // compute dest size
  32.     size_t len = src_len;
  33.     long int sub = (from_len - to_len)*count;
  34.    
  35.     // sanity check
  36.     if(from_len >= to_len) {
  37.         if(sub > len || sub < 0) return NULL;
  38.     } else {
  39.         if((len-sub) < 0 || sub > 0) return NULL;
  40.     }
  41.    
  42.     // allocate output buffer
  43.     size_t actual_size = (len - sub) + 1;
  44.     char *dest = malloc( actual_size );
  45.    
  46.     // fill output buffer
  47.     if(dest != NULL) {
  48.        
  49.         sp = src; // src pointer
  50.         dp = dest; // dest pointer
  51.        
  52.         while(1) {
  53.             mp = strstr(sp, from); // find next match
  54.             if(mp == NULL) break; // end of matches
  55.            
  56.             // copy chunk before match
  57.             memcpy(dp, sp, mp - sp);
  58.             dp += mp - sp;
  59.            
  60.             // copy replacement
  61.             memcpy(dp, to, to_len);
  62.             dp += to_len;
  63.            
  64.             // advance past match
  65.             sp = mp + from_len;
  66.         }
  67.        
  68.         // copy tail
  69.         size_t k = src_len - (sp - src) + 1;
  70.         memcpy(dp, sp, k);
  71.        
  72.     }
  73.    
  74.     return dest;
  75. }
Advertisement
Add Comment
Please, Sign In to add comment