这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑。。xsplit函数居然不能split连续2个空格,囧,领导说,你要是用ruby你就满分了,让我与满分失之交臂,当时没有人得满分,因此记忆深刻;

后来又是boost C++库流行,这个我就不说了,用过的都说好,但是也有些小麻烦,就是用的多了,编译就特别慢,那个时候还不知道用incredbuild,于是乎就在代码上下功夫了。

做了一些常用的字符操作,基本上python string的函数基本实现了,放在博客里,也可以温故知新。

xstring.h

 #ifndef XSTRING
#define XSTRING typedef struct xstring {
char *str;
struct xstring *next;
} xstring; //////////////////////////////////////////////////////////////////////////
void* allocate(size_t size); #ifdef USE_STD_MALLOC
#define dellocate(ptr) free(ptr);
#else
#define dellocate(ptr) mem_ret(ptr);
#endif //////////////////////////////////////////////////////////////////////////
xstring* xstring_new(size_t size);
void xstring_delete(xstring **head);
int xstring_size(xstring *head); //////////////////////////////////////////////////////////////////////////
size_t count(char* src, char* dst);
char* replace(char *src, char *old_val, char *new_val);
xstring* split(char *str, char *delimter);
char* strip(char *str);
char* lstrip(char *str);
char* rstrip(char *str);
int start_with(char *str, char *sym);
int end_with(char *str, char *sym);
char* uniq_seq_repeat_chars(char *str); #endif

xstring.c

 #include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "xstring.h"
#include "mem_pool.h" void* allocate(size_t size) {
#ifdef USE_STD_MALLOC
return malloc(size);
#else
return mem_get(size);
#endif
} xstring* xstring_new(size_t size) {
xstring *s = (xstring *)allocate(sizeof(xstring));
if (!s) return NULL; s->str = (char *)allocate(size+);
if (!s->str) {
dellocate(s);
return NULL;
} s->next = NULL;
return s;
} void xstring_delete(xstring** head) {
xstring *curr = *head;
xstring *next; while(curr) {
next = curr->next;
if (curr->str) dellocate(curr->str);
dellocate(curr);
curr = next;
}
*head = NULL;
return;
} int xstring_size(xstring* head) {
int size = ;
while (head) {
size++;
head = head->next;
}
return size;
} static void string_copy(char *dst, char *src, int len) {
if (!dst || !src) return;
strncpy(dst, src, len);
dst[len] = '\0';
return;
} static void substring_copy(xstring **curr, xstring *next, char *str, int len) {
string_copy(next->str, str, len);
(*curr)->next = next;
(*curr) = (*curr)->next;
} xstring* split(char* str, char *delimter) {
char *delimt, *buffer;
int i = ;
int len, match, cnt;
xstring *head = NULL;
xstring *next, *curr; if (NULL == str || NULL == delimter) return NULL; delimt = delimter;
len = strlen(delimter);
buffer = str;
match = ;
cnt = ; while (*buffer != '\0') {
if (*buffer == *delimt) {
delimt++;
match++;
} else if (*buffer != *delimt) {
delimt = delimter;
} if (match == len) {
if (NULL == head && cnt > ) {
head = xstring_new(cnt);
if (!head) return NULL;
string_copy(head->str, str+i-cnt, cnt+-len);
curr = head;
} else if (cnt > ){
next = xstring_new(cnt);
if (!next) return NULL;
substring_copy(&curr, next, str+i-cnt, cnt+-len);
}
cnt = ;
match = ;
delimt = delimter;
} else {
cnt++;
}
i++;
buffer++;
} if (cnt > ) {
next = xstring_new(cnt);
if (!next) return NULL;
substring_copy(&curr, next, str+i-cnt, cnt);
}
return head;
} size_t count(char* src, char* dst) {
size_t cnt = ;
char *buf = src;
char *tmp = dst;
int sum = ;
size_t len = strlen(dst); while (*buf != '\0') {
if (*buf == *tmp) {
sum++;
tmp++;
} else {
tmp = dst;
sum = ;
} if (sum == len) {
tmp = dst;
sum = ;
cnt++;
}
buf++;
}
return cnt;
} char* replace(char *src, char *old_val, char *new_val) {
if (!src || !old_val || !new_val) return NULL;
size_t cnt = count(src, old_val);
if ( == cnt) return NULL; size_t o_len = strlen(old_val);
size_t n_len = strlen(new_val);
size_t len = strlen(src) + cnt * (n_len - o_len) + ; char *new_str = (char *)allocate(len);
if (!new_str) return NULL; char *str = new_str;
char *buf = src;
char *tmp = old_val;
int sum = ; while (*buf != '\0') {
if (*buf == *tmp) {
sum++;
tmp++;
} else if (sum > ){
tmp = old_val;
sum = ;
} if (sum == ) *new_str++ = *buf;
if (sum == o_len) {
tmp = old_val;
sum = ;
for (size_t i=; i<n_len; i++) *new_str++ = new_val[i];
}
buf++;
} for(; sum>; sum--) *new_str++ = *(buf-sum);
*(str+len-) = '\0'; return str;
} char* lstrip(char *str) {
if (NULL == str) return NULL; char *tmp = str;
int i = ; while (isspace(*tmp++)) i++;
int len = strlen(str) - i; char *s = (char *)allocate(len + );
if (NULL == s) return NULL; string_copy(s, str+i, len);
return s;
} char* rstrip(char *str) {
if (NULL == str) return NULL;
char *tmp = str;
int len = strlen(str) - ; while (isspace(*(str+len))) len--; char *s = (char *)allocate(len + );
if (NULL == s) return NULL; string_copy(s, str, len+);
return s;
} char* strip(char *str) {
if (NULL == str) return NULL; char *tmp = str;
int len = strlen(str)-;
int i = ; while(isspace(*tmp++)) i++;
while(isspace(*(str+len))) len--; char *s = (char *)allocate(len-i+);
if (NULL == s) return NULL; string_copy(s, str+i, len-i+);
return s;
} int start_with(char *str, char *sym) {
if (!str || !sym || == strlen(sym)) return -;
return strncmp(str, sym, strlen(sym));
} int end_with(char *str, char *sym) {
if (!str || !sym) return -;
int l_len = strlen(str);
int r_len = strlen(sym); if (l_len < r_len ) return -;
return strncmp(str+l_len-r_len, sym, r_len);
} int max(int *in_arr, int len) {
assert(NULL != in_arr);
int m = in_arr[];
for(int i=; i<len; i++)
if (m < in_arr[i]) m = in_arr[i];
return m;
} char *uniq_seq_repeat_chars(char *str) {
if (NULL == str) return NULL; int rec[] = {};
char *s = (char *)allocate(strlen(str)+);
if (NULL == s) return NULL;
char *s1 = s; for (int i=; i<(int)strlen(str); i++) {
char ch = str[i];
if (rec[ch] == || != i-rec[ch]) {
*s = ch;
s++;
}
rec[ch] = i;
}
*s = '\0';
return s1;
}

重复造轮子系列--字符串处理(C语言)的更多相关文章

  1. 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关

    重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...

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

    重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...

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

    这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本. 因为没有内存边界检查: 因为没有内存使用统计: 因为没有考虑线程安全: 因为没有内存分配操作的具体文件位置信息: 因 ...

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

    前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧. spf.h #ifndef SPF_H_ #define SPF_H_ typedef struct { int ...

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

    在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...

  6. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

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

    1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...

  8. 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)

    一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...

  9. Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写(全部用POSIX C实现)

    Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写实现了日志.原子操作.哈希字典.红黑树.动态库加载.线程.锁操作.配置文件.os适配层.事件驱动.工作队列.RPC.IPC ...

随机推荐

  1. data-ng-app 指令

    1.data-ng-app指令定义了一个AngularJS应用程序的根元素. 2.data-ng-app会在页面加载完毕后自动进行初始化应用程序. 3.data-ng-app可以通过一个值连接到代码模 ...

  2. rnn,lstm and JuergenSchmidhuber

    JuergenSchmidhuber 是瑞士的一位牛人,主要贡献是rnn, lstm. google的deep mind新作,Human-level control through deep rein ...

  3. Linux 安装Oracle11g完整安装图文教程另附基本操作 (分享)

    一.修改操作系统核心参数 在Root用户下执行以下步骤: 1)修改用户的SHELL的限制,修改/etc/security/limits.conf文件 输入命令:vi /etc/security/lim ...

  4. vue面试常被问到的问题整理

    1.Vue的双向数据绑定原理是什么? 答 : vue是采用数据劫持,并且使用发布-订阅者的开发模式.原理是观察者observer通过Object.defineProperty()来劫持到各个属性的ge ...

  5. python导包学习总结

    python初学者,对于导包纠结了不少时间,总结分享,持续前进~ Python导包的两种方法: 1.1  from 包.模块  import 方法名,调用时直接使用方法名() 1.2  from 包. ...

  6. jupyter notebook中出现ValueError: signal only works in main thread 报错 即 长时间in[*] 解决办法

    我在jupyter notebook中新建了一个基于py3.6的kernel用来进行tensorflow学习 但是在jupyter notebook中建立该kernel时,右上角总是显示 服务正在启动 ...

  7. 裸机——Nand

    1.首先需要知道Nand的基础知识 从Nand的芯片手册可以获得 我使用的芯片手册是 K9F2G08 首先从芯片手册的名称可以获得信息: K9F:三星 2G   : 2Gb (256MB) 08    ...

  8. Pandas库入门

    pandas库的series类型

  9. <jsp:param>传参乱码问题

    在添加参数的界面添加<%request.setCharacterEncoding("UTF-8");%> 实例代码: login_confirm.jsp <%@ ...

  10. Androd安全——混淆技术完全解析

    .前言 在上一篇Androd安全--反编译技术完全解析中介绍了反编译方面的知识,因此我们认识到为了安全我们需要对代码进行混淆. 混淆代码并不是让代码无法被反编译,而是将代码中的类.方法.变量等信息进行 ...