这些字符代码是以前写的,源于很久很久以前的一个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. (jdbc和cmd)sqlite数据迁入mysql(导入导出)

    从sqlite进行导出数据 进行cmd命令 第一步:sqlite3->.open [文件路径](打开连接)->.tables(这个是查看表是否有没有)->.cd [切换的盘符](这里 ...

  2. Getting aCC Error :name followed by "::" must be a class or namespace name"

    Getting aCC Error :name followed by "::" must be a class or namespace name" 原始是这样子的: ...

  3. burpsuite 出现 ssl_error_no_cypher_overlap

    解决方案一:1.浏览器地址栏输入 about:config2.查找 security.tls.version.fallback-limit 和 security.tls.version.min,并将值 ...

  4. SpringBoot学习6:springboot文件上传

    1.编写页面uploadFile.html <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  5. Hibernate 异常总结

    异常一 异常一 异常描述: Sax解析异常:cvc-复杂的类型,发现了以元素maping开头的无效内容,应该是以 ‘{“http://www.hibernate.org/xsd/orm/cfg“:pr ...

  6. 在ubuntu中docker的简单使用(一)

    >>docker version 当运行docker version 命令出现Cannot connect to Docker daemon. Is the docker daemon r ...

  7. dubbo 与Spring Cloud 对比

    链接:https://www.zhihu.com/question/45413135/answer/242224410 近期也看到一些分享Spring Cloud的相关实施经验,这对于最近正在整理Sp ...

  8. lnamp高性能架构之apache和nginx的整合

    搭建过lamp博友和lnmp的博友们可能对这这两个单词并不陌生,对与apachen,nginx相比都源码或yum安装过,但知道apache的nginx的优点,apache处理动态页面很强,nginx处 ...

  9. PHP设计者---composer

    Composer 是 PHP5以上 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们.Composer 不是一个包管理器.是的,它涉及 "packages&q ...

  10. 怎样通过互联网ssh访问家里电脑

    需求:用可以上网的公司windows电脑连接家里的manjaro linux电脑.. 环境情况:公司电脑为内网,通过登录出口服务器连接互联网.家里的电脑也为内网,通过连接无线路由器连接外网.路由器有公 ...