str.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "str.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stddef.h>
  6. #include <stdbool.h>
  7. #include <stdarg.h>
  8. #include <ctype.h>
  9. char** str_split(char *str, char delim) {
  10. char **ret;
  11. if (str == NULL) return NULL;
  12. if (*str == '\n') {
  13. ret = malloc(sizeof(char*));
  14. *ret = NULL;
  15. return ret;
  16. }
  17. int count = 0;
  18. char *begin = str;
  19. for (char *p = str; *p != '\0'; p++) {
  20. if (*p != delim && !(delim == '\0' && isspace(*p))) {
  21. continue;
  22. }
  23. int size = p - begin;
  24. if (size > 0) count++;
  25. }
  26. count++;
  27. ret = malloc((count + 1) * sizeof(char*));
  28. memset(ret, 0, (count + 1) * sizeof(char*));
  29. begin = str;
  30. int i = 0;
  31. bool finished = false;
  32. for (char *p = str; !finished; p++) {
  33. if (*p == '\0') finished = true;
  34. if (*p != delim && *p != '\0' && !(delim == '\0' && isspace(*p))) {
  35. continue;
  36. }
  37. int size = p - begin;
  38. if (size == 0) {
  39. begin = p + 1;
  40. continue;
  41. }
  42. char *buf = malloc(sizeof(char) * (size + 1));
  43. buf[size] = '\0';
  44. memcpy(buf, begin, size * sizeof(char));
  45. begin = p + 1;
  46. ret[i] = buf;
  47. i++;
  48. }
  49. return ret;
  50. }
  51. void str_list_free(char **list) {
  52. char **p = list;
  53. while (*p != NULL) {
  54. free(*p);
  55. p++;
  56. }
  57. free(list);
  58. }
  59. char* str_strip(char *str) {
  60. int len = strlen(str);
  61. char *begin = str;
  62. char *end = str + len - 1;
  63. while (isspace(*begin) && begin < end) {
  64. begin++;
  65. }
  66. while (isspace(*end) && end >= begin) {
  67. end--;
  68. }
  69. len = end - begin + 1;
  70. char *buf = malloc(sizeof(char) * (len) + 1);
  71. buf[len] = '\0';
  72. memcpy(buf, begin, len);
  73. return buf;
  74. }
  75. void sb_init(StrBuilder *sb) {
  76. *sb = (StrBuilder){.size = 0, .cap = 16};
  77. sb->buf = malloc(sizeof(char) * 17);
  78. }
  79. static void sb_reserve(StrBuilder *sb, int extra) {
  80. if (sb->size + extra <= sb->cap) {
  81. return;
  82. }
  83. int new_cap = (sb->size + extra) * 2;
  84. sb->buf = realloc(sb->buf, new_cap + 1);
  85. memset(sb->buf + sb->cap, 0, new_cap - sb->cap + 1);
  86. sb->cap = new_cap;
  87. }
  88. void sb_append(StrBuilder *sb, char *format, ...) {
  89. va_list va1;
  90. va_list va2;
  91. va_start(va1, format);
  92. va_copy(va2, va1);
  93. int size = vsnprintf(NULL, 0, format, va1);
  94. sb_reserve(sb, size);
  95. vsnprintf(sb->buf + sb->size, sb->cap - sb->size + 1, format, va2);
  96. }
  97. void sb_appendc(StrBuilder *sb, char c) {
  98. sb_reserve(sb, 1);
  99. sb->buf[sb->size] = c;
  100. sb->size++;
  101. }
  102. char* fgetline(FILE *fp) {
  103. StrBuilder sb;
  104. sb_init(&sb);
  105. while (true) {
  106. int c = fgetc(fp);
  107. if (c == EOF && sb.size == 0) return NULL;
  108. if (c != EOF) sb_appendc(&sb, c);
  109. if (c == EOF || c == '\n') return sb.buf;
  110. }
  111. return NULL;
  112. }
  113. int fpeek(FILE *fp) {
  114. int c = fgetc(fp);
  115. if (c == EOF) return c;
  116. ungetc(c, fp);
  117. return c;
  118. }