string.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * 文件名: string.c
  3. * 目标: 关于char和wchar_t的实用函数
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdarg.h>
  9. #include "tool.h"
  10. #include "mem.h"
  11. char *charToStr(char ch) {
  12. if (ch == NUL)
  13. return NULL;
  14. char *tmp = NEW_STR(1);
  15. *tmp = ch;
  16. return tmp;
  17. }
  18. char *strCopy(const char *str){
  19. char *tmp = NEW_STR(STR_LEN(str));
  20. if (str != NULL)
  21. strcpy(tmp, str);
  22. return tmp;
  23. }
  24. wchar_t *wstrCopy(const wchar_t *str){
  25. wchar_t *tmp = NEW_WSTR(WSTR_LEN(str));
  26. if (str != NULL)
  27. wcscpy(tmp, str);
  28. return tmp;
  29. }
  30. /*
  31. * 函数名: wstrWithWchar
  32. * 目标: 赋值str到新空间,并且扩展 size 个大小, 若write为true则为扩展到大小写入...字符
  33. */
  34. wchar_t *wstrWithWchar(wchar_t *str, size_t size, int free_old, ...) { // free_base使用int而不是bool, 是因为va_start
  35. size_t base_len = WSTR_LEN(str);
  36. wchar_t *tmp = NEW_WSTR(base_len + size);
  37. if (base_len != 0)
  38. wcscpy(tmp, str);
  39. va_list va;
  40. va_start(va, free_old);
  41. for (int i = 0; i < size; i++)
  42. tmp[base_len + i] = (wchar_t)va_arg(va, int);
  43. va_end(va);
  44. if (free_old)
  45. free(str);
  46. return tmp;
  47. }
  48. /*
  49. * 函数名: wstrWithWchar_
  50. * 目标: 在str后增加一个新的字符
  51. */
  52. wchar_t *wstrWithWchar_(wchar_t *str, wint_t new, bool free_old) {
  53. size_t base_len = WSTR_LEN(str);
  54. wchar_t *tmp = NEW_WSTR(base_len + 1);
  55. if (base_len != 0)
  56. wcscpy(tmp, str);
  57. tmp[base_len] = new;
  58. if (free_old)
  59. free(str);
  60. return tmp;
  61. }
  62. /*
  63. * 函数名: wstrExpansion
  64. * 目标: 把str复制到新的空间, 并拓展其大小
  65. */
  66. wchar_t *wstrExpansion(wchar_t *str, size_t size, bool free_old) {
  67. size_t base_len = WSTR_LEN(str);
  68. wchar_t *tmp = NEW_WSTR(base_len + size);
  69. if (base_len != 0)
  70. wcscpy(tmp, str);
  71. if (free_old)
  72. free(str);
  73. return tmp;
  74. }
  75. /*
  76. * 函数名: strJoinIter
  77. * 目标: 在base后面拼接...字符串,...必须以NULL结尾
  78. */
  79. char *strJoinIter(char *base, int free_base, ...) { // free_base使用int而不是bool, 是因为va_start
  80. va_list ap;
  81. va_start(ap, free_base);
  82. for (char *ch = va_arg(ap, char *); ch != NULL; ch = va_arg(ap, char *)) {
  83. base = strJoin(base, ch, free_base, false);
  84. free_base = true;
  85. }
  86. va_end(ap);
  87. return base;
  88. }
  89. /*
  90. * 函数名: strJoin
  91. * 目标: 拼接两个字符串
  92. */
  93. char *strJoin(char *first, char *second, bool free_first, bool free_last) {
  94. if (first == NULL && second == NULL)
  95. return NULL;
  96. else if (first == NULL){
  97. first = second;
  98. second = NULL;
  99. free_first = free_last;
  100. free_last = false;
  101. }
  102. char *new = NEW_STR(STR_LEN(first) + STR_LEN(second));
  103. strcat(new, first);
  104. if (second != NULL)
  105. strcat(new, second);
  106. if (free_first)
  107. free(first);
  108. if (free_last)
  109. free(second);
  110. return new;
  111. }
  112. /*
  113. * 函数名: strJoin_
  114. * 目标: 拼接两个字符串, 比 strJoin 更快
  115. */
  116. char *strJoin_(char *first, char *second, bool free_first, bool free_last) {
  117. char *new = NEW_STR(STR_LEN(first) + STR_LEN(second));
  118. strcat(new, first);
  119. if (second != NULL)
  120. strcat(new, second);
  121. if (free_first)
  122. free(first);
  123. if (free_last)
  124. free(second);
  125. return new;
  126. }
  127. /*
  128. * 函数名: wstrJoin
  129. * 目标: 拼接两个宽字符串
  130. */
  131. wchar_t *wstrJoin(wchar_t *first, wchar_t *second, bool free_first, bool free_last) {
  132. if (first == NULL && second == NULL)
  133. return NULL;
  134. else if (first == NULL){
  135. first = second;
  136. second = NULL;
  137. free_first = free_last;
  138. free_last = false;
  139. }
  140. wchar_t *new = wstrExpansion(first, WSTR_LEN(second), false);
  141. if (second != NULL)
  142. wcscat(new, second);
  143. if (free_first)
  144. free(first);
  145. if (free_last)
  146. free(second);
  147. return new;
  148. }
  149. /*
  150. * 函数名: wstrJoin_
  151. * 目标: 拼接两个宽字符串, 比 wstrJoin 更快
  152. */
  153. wchar_t *wstrJoin_(wchar_t *first, wchar_t *second, bool free_first, bool free_last) {
  154. wchar_t *new = wstrExpansion(first, WSTR_LEN(second), false);
  155. if (second != NULL)
  156. wcscat(new, second);
  157. if (free_first)
  158. free(first);
  159. if (free_last)
  160. free(second);
  161. return new;
  162. }
  163. /*
  164. * 函数名: wstrCopySelf
  165. * 目标: 自我赋值 times 次, 若times小于0则会反转字符串
  166. */
  167. wchar_t *wstrCopySelf(wchar_t *str, long times){
  168. bool need_free = false;
  169. wchar_t *new_str = NULL;
  170. if (times < 0){
  171. str = wstrReverse(str);
  172. times = -times;
  173. need_free = true;
  174. }
  175. for (long i=0; i < times; i++)
  176. new_str = wstrJoin_(new_str, str, true, false);
  177. if (need_free)
  178. free(str);
  179. return new_str;
  180. }
  181. /*
  182. * 函数名: wstrReverse
  183. * 目标: 反转字符串
  184. */
  185. wchar_t *wstrReverse(wchar_t *str){
  186. size_t len_str = WSTR_LEN(str);
  187. wchar_t *new_str = NEW_WSTR(len_str);
  188. for (int i = 0;i < len_str;i++)
  189. new_str[i] = str[len_str - i - 1];
  190. return new_str;
  191. }
  192. /*
  193. * 函数名: convertToWstr
  194. * 目标: char *转换为wchar_t *
  195. */
  196. wchar_t *convertToWstr(char *str, bool free_old) {
  197. size_t len = STR_LEN(str);
  198. wchar_t *tmp = NEW_WSTR(len);
  199. mbstowcs(tmp, str, len);
  200. if (free_old)
  201. free(str);
  202. return tmp;
  203. }
  204. /*
  205. * 函数名: convertToStr
  206. * 目标: wchar_t *转换为char *
  207. */
  208. char *convertToStr(wchar_t *wstr, bool free_old) {
  209. size_t len = WSTR_LEN(wstr);
  210. char *tmp = NEW_STR(len);
  211. wcstombs(tmp, wstr, len);
  212. if (free_old)
  213. free(wstr);
  214. return tmp;
  215. }