aoc

Advent of code
git clone https://codeberg.org/night0721/aoc
Log | Files | Refs

util.c (2624B)


      1 #include <stddef.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <assert.h>
      5 #include <ctype.h>
      6 
      7 char **str_split(char* a_str, const char a_delim)
      8 {
      9     char** result    = 0;
     10     size_t count     = 0;
     11     char* tmp        = a_str;
     12     char* last_comma = 0;
     13     char delim[2];
     14     delim[0] = a_delim;
     15     delim[1] = 0;
     16     /* Count how many elements will be extracted. */
     17     while (*tmp)
     18     {
     19         if (a_delim == *tmp)
     20         {
     21             count++;
     22             last_comma = tmp;
     23         }
     24         tmp++;
     25     }
     26     /* Add space for trailing token. */
     27     count += last_comma < (a_str + strlen(a_str) - 1);
     28     /* Add space for terminating null string so caller
     29        knows where the list of returned strings ends. */
     30     count++;
     31     result = malloc(sizeof(char*) * count);
     32     if (result)
     33     {
     34         size_t idx  = 0;
     35         char* token = strtok(a_str, delim);
     36         while (token)
     37         {
     38             assert(idx < count);
     39             *(result + idx++) = strdup(token);
     40             token = strtok(0, delim);
     41         }
     42         assert(idx == count - 1);
     43         *(result + idx) = 0;
     44     }
     45     return result;
     46 }
     47 
     48 // Note: This function returns a pointer to a substring of the original string.
     49 // If the given string was allocated dynamically, the caller must not overwrite
     50 // that pointer with the returned value, since the original pointer must be
     51 // deallocated using the same allocator with which it was allocated.  The return
     52 // value must NOT be deallocated using free() etc.
     53 char *trimwhitespace(char *str)
     54 {
     55     char *end;
     56     // Trim leading space
     57     while(isspace((unsigned char)*str)) str++;
     58     if(*str == 0)  // All spaces?
     59         return str;
     60     // Trim trailing space
     61     end = str + strlen(str) - 1;
     62     while(end > str && isspace((unsigned char)*end)) end--;
     63     // Write new null terminator character
     64     end[1] = '\0';
     65     return str;
     66 }
     67 
     68 void replace(char *target, const char *needle, const char *replacement)
     69 {
     70     char buffer[1024] = { 0 };
     71     char *insert_point = &buffer[0];
     72     const char *tmp = target;
     73     size_t needle_len = strlen(needle);
     74     size_t repl_len = strlen(replacement);
     75     while (1) {
     76         const char *p = strstr(tmp, needle);
     77         if (p == NULL) { // walked past last occurrence of needle; copy remaining part
     78             strcpy(insert_point, tmp);
     79             break;
     80         }
     81         memcpy(insert_point, tmp, p - tmp); // copy part before needle
     82         insert_point += p - tmp;
     83         memcpy(insert_point, replacement, repl_len); // copy replacement string
     84         insert_point += repl_len;
     85         tmp = p + needle_len;
     86     }
     87     strcpy(target, buffer);
     88 }