str_split.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. size_t split_count(char* a_str, const char a_delim) {
  6. char* tmp = a_str;
  7. char* last_comma = 0;
  8. size_t count = 0;
  9. while (*tmp) {
  10. if (a_delim == *tmp) {
  11. count++;
  12. last_comma = tmp;
  13. }
  14. tmp++;
  15. }
  16. // Add space for trailing token.
  17. count += last_comma < (a_str + strlen(a_str) - 1);
  18. // Add space for terminating null string.
  19. count++;
  20. return count;
  21. }
  22. /* Adapted from http://stackoverflow.com/a/9210560 */
  23. char** str_split(char* a_str, const char a_delim) {
  24. char delim[2];
  25. delim[0] = a_delim;
  26. delim[1] = 0;
  27. size_t count = split_count(a_str, a_delim);
  28. char** result = malloc(sizeof(char*) * count);
  29. if(!result) {
  30. fprintf(stderr, "Failed to allocate memory when splitting string '%s'.\n", a_str);
  31. return NULL;
  32. }
  33. if(result) {
  34. size_t idx = 0;
  35. char* token = strtok(a_str, delim);
  36. while (token) {
  37. assert(idx < count);
  38. *(result + idx++) = strdup(token);
  39. token = strtok(0, delim);
  40. }
  41. assert(idx == count - 1);
  42. *(result + idx) = 0;
  43. }
  44. return result;
  45. }
  46. void substring(char* substr, const char* string, size_t start, size_t end) {
  47. if(end > strlen(string)) {
  48. end = strlen(string);
  49. }
  50. if(start < 0) {
  51. start = 0;
  52. }
  53. if(end < start) {
  54. return NULL;
  55. }
  56. size_t nchars = end - start + 1; // Need +1 because substring should include both ends.
  57. memcpy(substr, &string[start], nchars);
  58. substr[nchars] = '\0';
  59. }
  60. /* Adapted from http://stackoverflow.com/a/12890107 */
  61. char* replace(const char *src, char ch, const char *repl) {
  62. int count = 0;
  63. const char *tmp;
  64. for(tmp=src; *tmp; tmp++)
  65. count += (*tmp == ch);
  66. size_t rlen = strlen(repl);
  67. char *res = malloc(strlen(src) + (rlen-1)*count + 1);
  68. char *ptr = res;
  69. for(tmp=src; *tmp; tmp++) {
  70. if(*tmp == ch) {
  71. memcpy(ptr, repl, rlen);
  72. ptr += rlen;
  73. } else {
  74. *ptr++ = *tmp;
  75. }
  76. }
  77. *ptr = 0;
  78. return res;
  79. }