重复造轮子系列--字符串处理(C语言)
这些字符代码是以前写的,源于很久很久以前的一个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语言)的更多相关文章
- 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关
重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- 重复造轮子系列--内存池(C语言)
这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本. 因为没有内存边界检查: 因为没有内存使用统计: 因为没有考虑线程安全: 因为没有内存分配操作的具体文件位置信息: 因 ...
- 重复造轮子系列--dijkstra算法
前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧. spf.h #ifndef SPF_H_ #define SPF_H_ typedef struct { int ...
- 第27篇 重复造轮子---模拟IIS服务器
在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
- 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)
一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...
- Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写(全部用POSIX C实现)
Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写实现了日志.原子操作.哈希字典.红黑树.动态库加载.线程.锁操作.配置文件.os适配层.事件驱动.工作队列.RPC.IPC ...
随机推荐
- node.js启动调试方式
node.js启动调试方式(nodeJs不能像js一样在控制台调试) 以express项目为例,启动路径是localhost:3000 一.通过node命令启动 node server/bin/www ...
- linux中安装JDK linux中安装Tomcat linux中安装Mysql 及故障解析 linux系统安装redis
Linux 安装JDK 配置完环境变量后无法使用 java -version 无法打开 通过下面语句 将32位文件与当前系统64位兼容 (有待补充32位查法)sudo yum install glib ...
- ReactiveObjC框架的简单介绍
最近在一直在学习RAC框架的Object-C版本ReactiveObjC(Swift版本为ReactiveSwift),这篇文章简单展示一下学习的成果!!!如果有什么地方理解错误,欢迎大家指正!!!互 ...
- 服务器操作nginx相关操作命令
服务器操作nginx相关操作命令 登录服务器: ssh root@0.0.0.0 -p 22100 启动nginx: /usr/local/nginx/sbin/nginx 查看nginx是否启动 p ...
- 关于event loop
之前写了篇文章 JS运行机制,里面对event loop简单的说明,面试时又遇到了关于该知识点的题目(主要是process.nextTick和setImmediate的执行顺序不太知道,查了之后才知道 ...
- Web as a App(Web既APP)的概念可以提出吗?
Web as a App (WaaA),Web既APP.灵感出于SaaS.PaaS.IaaS等~ 最近在做一个PC项目,即便我的项目是to B的,用户量没那么大,但是我仍然很注重性能及用户体验,我把我 ...
- 连接mysql 报错 Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
网上找不到 朋友说是因为非正常关机导致,mysql.server start 运行报错 ERROR! The server quit without updating PID file(): 解决办 ...
- scrapy--BeautifulSoup
BeautifulSoup官方文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/#id8 太繁琐的,精简了一些自己用的到的. 1.index.h ...
- laravel-多条件查询并指定key输出
$room = DB::table('room') ->where(function($query) use($contList){ foreach ($contList as $k=>$ ...
- HAN模型理解1
HAN 模型 最开始看这个模型是看的这个解释: RNN+Attention(HAN) 文本分类 阅读笔记 - 今天做作业没的文章 - 知乎 https://zhuanlan.zhihu.com/p/4 ...