str.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:6k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/str.doc,v 1.10 1996/06/26 23:02:01 drh Exp $";
  2. #include <string.h>
  3. #include <limits.h>
  4. #include "assert.h"
  5. #include "fmt.h"
  6. #include "str.h"
  7. #include "mem.h"
  8. #define idx(i, len) ((i) <= 0 ? (i) + (len) : (i) - 1)
  9. #define convert(s, i, j) do { int len; 
  10. assert(s); len = strlen(s); 
  11. i = idx(i, len); j = idx(j, len); 
  12. if (i > j) { int t = i; i = j; j = t; } 
  13. assert(i >= 0 && j <= len); } while (0)
  14. char *Str_sub(const char *s, int i, int j) {
  15. char *str, *p;
  16. convert(s, i, j);
  17. p = str = ALLOC(j - i + 1);
  18. while (i < j)
  19. *p++ = s[i++];
  20. *p = '';
  21. return str;
  22. }
  23. char *Str_dup(const char *s, int i, int j, int n) {
  24. int k;
  25. char *str, *p;
  26. assert(n >= 0);
  27. convert(s, i, j);
  28. p = str = ALLOC(n*(j - i) + 1);
  29. if (j - i > 0)
  30. while (n-- > 0)
  31. for (k = i; k < j; k++)
  32. *p++ = s[k];
  33. *p = '';
  34. return str;
  35. }
  36. char *Str_reverse(const char *s, int i, int j) {
  37. char *str, *p;
  38. convert(s, i, j);
  39. p = str = ALLOC(j - i + 1);
  40. while (j > i)
  41. *p++ = s[--j];
  42. *p = '';
  43. return str;
  44. }
  45. char *Str_cat(const char *s1, int i1, int j1,
  46.               const char *s2, int i2, int j2) {
  47. char *str, *p;
  48. convert(s1, i1, j1);
  49. convert(s2, i2, j2);
  50. p = str = ALLOC(j1 - i1 + j2 - i2 + 1);
  51. while (i1 < j1)
  52. *p++ = s1[i1++];
  53. while (i2 < j2)
  54. *p++ = s2[i2++];
  55. *p = '';
  56. return str;
  57. }
  58. char *Str_catv(const char *s, ...) {
  59. char *str, *p;
  60. const char *save = s;
  61. int i, j, len = 0;
  62. va_list ap;
  63. va_start(ap, s);
  64. while (s) {
  65. i = va_arg(ap, int);
  66. j = va_arg(ap, int);
  67. convert(s, i, j);
  68. len += j - i;
  69. s = va_arg(ap, const char *);
  70. }
  71. va_end(ap);
  72. p = str = ALLOC(len + 1);
  73. s = save;
  74. va_start(ap, s);
  75. while (s) {
  76. i = va_arg(ap, int);
  77. j = va_arg(ap, int);
  78. convert(s, i, j);
  79. while (i < j)
  80. *p++ = s[i++];
  81. s = va_arg(ap, const char *);
  82. }
  83. va_end(ap);
  84. *p = '';
  85. return str;
  86. }
  87. char *Str_map(const char *s, int i, int j,
  88. const char *from, const char *to) {
  89. static char map[256] = { 0 };
  90. if (from && to) {
  91. unsigned c;
  92. for (c = 0; c < sizeof map; c++)
  93. map[c] = c;
  94. while (*from && *to)
  95. map[(unsigned char)*from++] = *to++;
  96. assert(*from == 0 && *to == 0);
  97. } else {
  98. assert(from == NULL && to == NULL && s);
  99. assert(map['a']);
  100. }
  101. if (s) {
  102. char *str, *p;
  103. convert(s, i, j);
  104. p = str = ALLOC(j - i + 1);
  105. while (i < j)
  106. *p++ = map[(unsigned char)s[i++]];
  107. *p = '';
  108. return str;
  109. } else
  110. return NULL;
  111. }
  112. int Str_pos(const char *s, int i) {
  113. int len;
  114. assert(s);
  115. len = strlen(s);
  116. i = idx(i, len);
  117. assert(i >= 0 && i <= len);
  118. return i + 1;
  119. }
  120. int Str_len(const char *s, int i, int j) {
  121. convert(s, i, j);
  122. return j - i;
  123. }
  124. int Str_cmp(const char *s1, int i1, int j1,
  125. const char *s2, int i2, int j2) {
  126. convert(s1, i1, j1);
  127. convert(s2, i2, j2);
  128. s1 += i1;
  129. s2 += i2;
  130. if (j1 - i1 < j2 - i2) {
  131. int cond = strncmp(s1, s2, j1 - i1);
  132. return cond == 0 ? -1 : cond;
  133. } else if (j1 - i1 > j2 - i2) {
  134. int cond = strncmp(s1, s2, j2 - i2);
  135. return cond == 0 ? +1 : cond;
  136. } else
  137. return strncmp(s1, s2, j1 - i1);
  138. }
  139. int Str_chr(const char *s, int i, int j, int c) {
  140. convert(s, i, j);
  141. for ( ; i < j; i++)
  142. if (s[i] == c)
  143. return i + 1;
  144. return 0;
  145. }
  146. int Str_rchr(const char *s, int i, int j, int c) {
  147. convert(s, i, j);
  148. while (j > i)
  149. if (s[--j] == c)
  150. return j + 1;
  151. return 0;
  152. }
  153. int Str_upto(const char *s, int i, int j,
  154. const char *set) {
  155. assert(set);
  156. convert(s, i, j);
  157. for ( ; i < j; i++)
  158. if (strchr(set, s[i]))
  159. return i + 1;
  160. return 0;
  161. }
  162. int Str_rupto(const char *s, int i, int j,
  163. const char *set) {
  164. assert(set);
  165. convert(s, i, j);
  166. while (j > i)
  167. if (strchr(set, s[--j]))
  168. return j + 1;
  169. return 0;
  170. }
  171. int Str_find(const char *s, int i, int j,
  172. const char *str) {
  173. int len;
  174. convert(s, i, j);
  175. assert(str);
  176. len = strlen(str);
  177. if (len == 0)
  178. return i + 1;
  179. else if (len == 1) {
  180. for ( ; i < j; i++)
  181. if (s[i] == *str)
  182. return i + 1;
  183. } else
  184. for ( ; i + len <= j; i++)
  185. if ((strncmp(&s[i], str, len) == 0))
  186. return i + 1;
  187. return 0;
  188. }
  189. int Str_rfind(const char *s, int i, int j,
  190. const char *str) {
  191. int len;
  192. convert(s, i, j);
  193. assert(str);
  194. len = strlen(str);
  195. if (len == 0)
  196. return j + 1;
  197. else if (len == 1) {
  198. while (j > i)
  199. if (s[--j] == *str)
  200. return j + 1;
  201. } else
  202. for ( ; j - len >= i; j--)
  203. if (strncmp(&s[j-len], str, len) == 0)
  204. return j - len + 1;
  205. return 0;
  206. }
  207. int Str_any(const char *s, int i, const char *set) {
  208. int len;
  209. assert(s);
  210. assert(set);
  211. len = strlen(s);
  212. i = idx(i, len);
  213. assert(i >= 0 && i <= len);
  214. if (i < len && strchr(set, s[i]))
  215. return i + 2;
  216. return 0;
  217. }
  218. int Str_many(const char *s, int i, int j,
  219. const char *set) {
  220. assert(set);
  221. convert(s, i, j);
  222. if (i < j && strchr(set, s[i])) {
  223. do
  224. i++;
  225. while (i < j && strchr(set, s[i]));
  226. return i + 1;
  227. }
  228. return 0;
  229. }
  230. int Str_rmany(const char *s, int i, int j,
  231. const char *set) {
  232. assert(set);
  233. convert(s, i, j);
  234. if (j > i && strchr(set, s[j-1])) {
  235. do
  236. --j;
  237. while (j >= i && strchr(set, s[j]));
  238. return j + 2;
  239. }
  240. return 0;
  241. }
  242. int Str_match(const char *s, int i, int j,
  243. const char *str) {
  244. int len;
  245. convert(s, i, j);
  246. assert(str);
  247. len = strlen(str);
  248. if (len == 0)
  249. return i + 1; 
  250. else if (len == 1) {
  251. if (i < j && s[i] == *str)
  252. return i + 2;
  253. } else if (i + len <= j && (strncmp(&s[i], str, len) == 0))
  254. return i + len + 1;
  255. return 0;
  256. }
  257. int Str_rmatch(const char *s, int i, int j,
  258. const char *str) {
  259. int len;
  260. convert(s, i, j);
  261. assert(str);
  262. len = strlen(str);
  263. if (len == 0)
  264. return j + 1;
  265. else if (len == 1) {
  266. if (j > i && s[j-1] == *str)
  267. return j;
  268. } else if (j - len >= i
  269. && strncmp(&s[j-len], str, len) == 0)
  270. return j - len + 1;
  271. return 0;
  272. }
  273. void Str_fmt(int code, va_list *app,
  274. int put(int c, void *cl), void *cl,
  275. unsigned char flags[], int width, int precision) {
  276. char *s;
  277. int i, j;
  278. assert(app && flags);
  279. s = va_arg(*app, char *);
  280. i = va_arg(*app, int);
  281. j = va_arg(*app, int);
  282. convert(s, i, j);
  283. Fmt_puts(s + i, j - i, put, cl, flags,
  284. width, precision);
  285. }