重复造轮子系列--字符串常用操作(C语言)

xstring.h

 1 #ifndef XSTRING
 2 #define XSTRING
 3
 4 typedef struct xstring {
 5     char *str;
 6     struct xstring *next;
 7 } xstring;
 8
 9
10 //////////////////////////////////////////////////////////////////////////
11 void*    allocate(size_t size);
12
13 #ifdef USE_STD_MALLOC
14 #define dellocate(ptr) free(ptr);
15 #else
16 #define dellocate(ptr) mem_ret(ptr);
17 #endif
18
19 //////////////////////////////////////////////////////////////////////////
20 xstring* xstring_new(size_t size);
21 void     xstring_delete(xstring **head);
22 int      xstring_size(xstring *head);
23
24 //////////////////////////////////////////////////////////////////////////
25 size_t   count(char* src, char* dst);
26 char*    replace(char *src, char *old_val, char *new_val);
27 xstring* split(char *str, char *delimter);
28 char*    strip(char *str);
29 char*    lstrip(char *str);
30 char*    rstrip(char *str);
31 int      start_with(char *str, char *sym);
32 int      end_with(char *str, char *sym);
33 char*    uniq_seq_repeat_chars(char *str);
34
35 #endif

xstring.c

  1 #include <stdlib.h>
  2 #include <string.h>
  3 #include <ctype.h>
  4 #include <assert.h>
  5 #include "xstring.h"
  6 #include "mem_pool.h"
  7
  8 void* allocate(size_t size) {
  9 #ifdef USE_STD_MALLOC
 10     return malloc(size);
 11 #else
 12     return mem_get(size);
 13 #endif
 14 }
 15
 16 xstring* xstring_new(size_t size) {
 17     xstring *s = (xstring *)allocate(sizeof(xstring));
 18     if (!s) return NULL;
 19
 20     s->str = (char *)allocate(size+1);
 21     if (!s->str) {
 22         dellocate(s);
 23         return NULL;
 24     }
 25
 26     s->next = NULL;
 27     return s;
 28 }
 29
 30 void xstring_delete(xstring** head) {
 31     xstring *curr = *head;
 32     xstring *next;
 33
 34     while(curr) {
 35         next = curr->next;
 36         if (curr->str) dellocate(curr->str);
 37         dellocate(curr);
 38         curr = next;
 39     }
 40     *head = NULL;
 41     return;
 42 }
 43
 44 int xstring_size(xstring* head) {
 45     int size = 0;
 46     while (head) {
 47         size++;
 48         head = head->next;
 49     }
 50     return size;
 51 }
 52
 53 static void string_copy(char *dst, char *src, int len) {
 54     if (!dst || !src) return;
 55     strncpy(dst, src, len);
 56     dst[len] = ‘\0‘;
 57     return;
 58 }
 59
 60 static void substring_copy(xstring **curr, xstring *next, char *str, int len) {
 61     string_copy(next->str, str, len);
 62     (*curr)->next = next;
 63     (*curr) = (*curr)->next;
 64 }
 65
 66 xstring* split(char* str, char *delimter) {
 67     char *delimt, *buffer;
 68     int i = 0;
 69     int len, match, cnt;
 70     xstring *head = NULL;
 71     xstring *next, *curr;
 72
 73     if (NULL == str || NULL == delimter) return NULL;
 74
 75     delimt = delimter;
 76     len    = strlen(delimter);
 77     buffer = str;
 78     match  = 0;
 79     cnt    = 0;
 80
 81     while (*buffer != ‘\0‘) {
 82         if (*buffer == *delimt) {
 83             delimt++;
 84             match++;
 85         } else if (*buffer != *delimt) {
 86             delimt = delimter;
 87         }
 88
 89         if (match == len) {
 90             if (NULL == head && cnt > 0) {
 91                 head = xstring_new(cnt);
 92                 if (!head) return NULL;
 93                 string_copy(head->str, str+i-cnt, cnt+1-len);
 94                 curr = head;
 95             } else if (cnt > 0){
 96                 next = xstring_new(cnt);
 97                 if (!next) return NULL;
 98                 substring_copy(&curr, next, str+i-cnt, cnt+1-len);
 99             }
100             cnt    = 0;
101             match  = 0;
102             delimt = delimter;
103         } else {
104             cnt++;
105         }
106         i++;
107         buffer++;
108     }
109
110     if (cnt > 0) {
111         next = xstring_new(cnt);
112         if (!next) return NULL;
113         substring_copy(&curr, next, str+i-cnt, cnt);
114     }
115     return head;
116 }
117
118 size_t count(char* src, char* dst) {
119     size_t cnt = 0;
120     char *buf = src;
121     char *tmp = dst;
122     int sum = 0;
123     size_t len = strlen(dst);
124
125     while (*buf != ‘\0‘) {
126         if (*buf == *tmp) {
127             sum++;
128             tmp++;
129         } else {
130             tmp = dst;
131             sum = 0;
132         }
133
134         if (sum == len) {
135             tmp = dst;
136             sum = 0;
137             cnt++;
138         }
139         buf++;
140     }
141     return cnt;
142 }
143
144 char* replace(char *src, char *old_val, char *new_val) {
145     if (!src || !old_val || !new_val) return NULL;
146     size_t cnt = count(src, old_val);
147     if (0 == cnt) return NULL;
148
149     size_t o_len = strlen(old_val);
150     size_t n_len = strlen(new_val);
151     size_t len   = strlen(src)  + cnt * (n_len - o_len) + 1;
152
153     char *new_str = (char *)allocate(len);
154     if (!new_str) return NULL;
155
156     char *str = new_str;
157     char *buf = src;
158     char *tmp = old_val;
159     int   sum = 0;
160
161     while (*buf != ‘\0‘) {
162         if (*buf == *tmp) {
163             sum++;
164             tmp++;
165         } else if (sum > 0){
166             tmp = old_val;
167             sum = 0;
168         }
169
170         if (sum == 0) *new_str++ = *buf;
171         if (sum == o_len) {
172             tmp = old_val;
173             sum = 0;
174             for (size_t i=0; i<n_len; i++) *new_str++ = new_val[i];
175         }
176         buf++;
177     }
178
179     for(; sum>0; sum--) *new_str++ = *(buf-sum);
180     *(str+len-1) = ‘\0‘;
181
182     return str;
183 }
184
185 char* lstrip(char *str) {
186     if (NULL == str) return NULL;
187
188     char *tmp = str;
189     int i = 0;
190
191     while (isspace(*tmp++)) i++;
192     int len = strlen(str) - i;
193
194     char *s = (char *)allocate(len + 1);
195     if (NULL == s) return NULL;
196
197     string_copy(s, str+i, len);
198     return s;
199 }
200
201 char* rstrip(char *str) {
202     if (NULL == str) return NULL;
203     char *tmp = str;
204     int len = strlen(str) - 1;
205
206     while (isspace(*(str+len))) len--;
207
208     char *s = (char *)allocate(len + 2);
209     if (NULL == s) return NULL;
210
211     string_copy(s, str, len+1);
212     return s;
213 }
214
215 char* strip(char *str) {
216     if (NULL == str) return NULL;
217
218     char *tmp = str;
219     int len = strlen(str)-1;
220     int i = 0;
221
222     while(isspace(*tmp++)) i++;
223     while(isspace(*(str+len))) len--;
224
225     char *s = (char *)allocate(len-i+2);
226     if (NULL == s) return NULL;
227
228     string_copy(s, str+i, len-i+1);
229     return s;
230 }
231
232 int start_with(char *str, char *sym) {
233     if (!str || !sym || 0 == strlen(sym)) return -1;
234     return strncmp(str, sym, strlen(sym));
235 }
236
237 int end_with(char *str, char *sym) {
238     if (!str || !sym) return -1;
239     int l_len = strlen(str);
240     int r_len = strlen(sym);
241
242     if (l_len < r_len ) return -1;
243     return strncmp(str+l_len-r_len, sym, r_len);
244 }
245
246 int max(int *in_arr, int len) {
247     assert(NULL != in_arr);
248     int m = in_arr[0];
249     for(int i=0; i<len; i++)
250         if (m < in_arr[i]) m = in_arr[i];
251     return m;
252 }
253
254 char *uniq_seq_repeat_chars(char *str) {
255     if (NULL == str) return NULL;
256
257     int rec[256] = {0};
258     char *s = (char *)allocate(strlen(str)+1);
259     if (NULL == s) return NULL;
260     char *s1 = s;
261
262     for (int i=0; i<(int)strlen(str); i++) {
263         char ch = str[i];
264         if (rec[ch] == 0 || 1 != i-rec[ch]) {
265             *s = ch;
266             s++;
267         }
268         rec[ch] = i;
269     }
270     *s = ‘\0‘;
271     return s1;
272 }
时间: 2024-10-06 16:04:14

重复造轮子系列--字符串常用操作(C语言)的相关文章

重复造轮子系列--内存池(C语言)

mem_pool.h 1 #ifndef MEM_POOL_H_ 2 #define MEM_POOL_H_ 3 4 typedef struct MemBlock { 5 struct MemBlock* next; 6 int size; 7 void *ptr; 8 } MemBlock; 9 10 typedef unsigned char byte; 11 12 // 8 16 32 64 128 256 512 1024 2048 4096 13 // 1 2 4 8 16 32 6

重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印

重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端系统打印经常使用的场景. 1.一种是类似票务方面的系统需要打印固定格式的票据.比如景点门票.车票.电影票. 这种基本是根据模板调整位置套打. 2.还有一种是交易小票,比如商超POS小票,打印长度会随着内容的大小自动伸缩. 这种就不仅仅是固定格式的套打了,还得计算数据行以适应不同的打印长度. 打印方式

重复造轮子系列--桶排序

理解了基数排序,也就理解了桶排序. 桶排序就是基数排序的一种优化,从MSD开始,即取最高位来排一次序,如果最高位没有重复(意味着没有冲突需要处理),是算法的最佳状态,O(n). 如果有冲突,就将冲突的元素存放到对应的桶里(代码就是一个链表或者数组或者stl容器),然后对每个桶进行一次插入排序,平均情况的话冲突很小的,桶里的元素的数量就不多,速度很快, 如果冲突集中在几个桶甚至一个桶里,那么就出现了算法的最差情形,也就是O(n^2)的复杂度. 下面是例子代码实现: 1 template<typen

重复造轮子系列--计数,基数排序

计数,基数的中文读音都一样,这翻译的人还嫌我们计算机不够乱,真的想吐槽. 不管了,毕竟代码还是不一样的. 1.计数排序(counter sort): 通过一个上限来统计集合里的数值(或者其他非数值类型映射的数值),并累计比小于自己(包括)的数值的统计的个数,从而形成排序的索引(也就是前面有多少个小于我的,我的位置就确定了). 普通计数排序代码:(仍需优化,valuetype默认是整数类型) 1 template<typename _InIt> 2 void counter_sort(_InIt

重复造轮子系列--插入排序和归并排序

囧,道理很简单,实践起来却不容易. 因为编程语言跟算法描述数据结构并不能完全一致,所以理论到实践还是有些出入的. 下面的例子是没有哨兵位置的实现: 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <cassert> 5 6 using namespace std; 7 8 template<typename _InIt, typename _Func

重复造轮子系列--dijkstra算法

spf.h 1 #ifndef SPF_H_ 2 #define SPF_H_ 3 4 5 typedef struct { 6 int length; 7 char src; 8 char dst; 9 char prev_hop; 10 } dijkstra; 11 12 #define MAX 1024 13 #define NODE_NUM 5 14 #define TRUE 1 15 #define FALSE 0 16 17 #endif spf.c 1 #include <stdi

GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便地使用所有版本的Android动作栏的设计模式. 对于Android 4.0及更高版本,ActionBarSherlock可以自动使用本地ActionBar实现,而对于之前没有ActionBar功能的版本,基于Ice Cream Sandwich的自定义动作栏实现将自动围绕布局.能够让开发者轻松开发

第27篇 重复造轮子---模拟IIS服务器

在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西是一个更好的理解和使用.   当你打开一个网页时,你会看到一个html页面的呈现,当然这是一个完整的Http的请求和响应的过程,无非是对HTML+CSS+JS一个综合的产物,在这个过程中浏览器请求数据的过程中会发出一个有一个格式的字符串(基于http协议生成的http请求报文),服务器在接收这样的一

python列表、字典、字符串常用操作

Python 列表.字典.字符串常用操作 1.字符串操作 字符串可以通过下标取值,但由于字符串是不可变变量,不可通过下标来修改值. str = 'lily terry mark' name[0]    #获取第1个字符串值 name[0:7]   #获取第1~7的字符串值 name[:7]   #缺省开始位置,默认从第1个元素开始取值 name[0:]   #缺省结束位置,默认到字符串末尾结束 字符串包含判断操作符:in .not in .is 'lily' in names 'lily' no