C语言模拟php basename() 函数
2016-04-12 00:45
603 查看
项目中要获取一个文件路径的文件名称,这让我想起了php中的basename()函数。于是看了php中的实现basename()函数的源码:
源码如下:
这段代码刚开始看挺费劲,state从0变成1,又从1变成0,想了半天终于是弄清楚逻辑了。不由感叹这段代码的神奇,如同一幅太极图,你中有我,我中有你,相互呼应。
然而,这段代码感觉并不高效。我们传入的路径通常很长,比如下面这个路径:
/Users/Library/Developer/CoreSimulator/Devices/5FEEB80E-8EA7-4090-A943-C1C033671D54/data/Containers/Data/Application/E3F82D85-A99A-475C-A467-F999226F3235/app.html。上面这个代码从头开始遍历,边遍历边判断。而我们最后要的结果恰好是在最后,这也就带来了性能的浪费。在这样的情况下,我们完全可以倒着遍历字符串。如下代码所示
上面的效率比较都是基于自我感觉的,更加严谨的比较需要通过测试。不过从代码可读性来说,自认为下面的代码更强一些,以后维护起来也方便
源码如下:
void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len) { char *ret = NULL, *c, *comp, *cend; size_t inc_len, cnt; int state; c = comp = cend = s; cnt = len; state = 0; while (cnt > 0) { inc_len = 1; if (*c == '/' || *c == '\\') { if (state == 1) { state = 0; cend = c; } } else { if (state == 0) { comp = c; state = 1; } } c += inc_len; cnt -= inc_len; } if (state == 1) { cend = c; } if (suffix != NULL && sufflen < (size_t)(cend - comp) && memcmp(cend - sufflen, suffix, sufflen) == 0) { cend -= sufflen; } len = cend - comp; if (p_ret) { ret = malloc(len + 1); memcpy(ret, comp, len); ret[len] = '\0'; *p_ret = ret; } if (p_len) { *p_len = len; } } /* }}} */ /* {{{ proto string basename(string path [, string suffix]) Returns the filename component of the path */ char *basename(char *string, char *suffix) { char *ret; int string_len = strlen(string), suffix_len = strlen(suffix); size_t ret_len; php_basename(string, string_len, suffix, suffix_len, &ret, &ret_len); return ret; } 来源:http://demon.tw/programming/c-php-basename.html
这段代码刚开始看挺费劲,state从0变成1,又从1变成0,想了半天终于是弄清楚逻辑了。不由感叹这段代码的神奇,如同一幅太极图,你中有我,我中有你,相互呼应。
然而,这段代码感觉并不高效。我们传入的路径通常很长,比如下面这个路径:
/Users/Library/Developer/CoreSimulator/Devices/5FEEB80E-8EA7-4090-A943-C1C033671D54/data/Containers/Data/Application/E3F82D85-A99A-475C-A467-F999226F3235/app.html。上面这个代码从头开始遍历,边遍历边判断。而我们最后要的结果恰好是在最后,这也就带来了性能的浪费。在这样的情况下,我们完全可以倒着遍历字符串。如下代码所示
void baseNameHandle(char*s,char**p_ret) { char* _ret[30]={0}; int nLen=strlen(s); int iPos=nLen-1; while(s[iPos]!=’\\’&&pFilePath[iPos]!=’/’) { --iPos; } strncpy(_ret,s+iPos+1,nLen-iPos-1); *p_ret=_ret; }
上面的效率比较都是基于自我感觉的,更加严谨的比较需要通过测试。不过从代码可读性来说,自认为下面的代码更强一些,以后维护起来也方便
相关文章推荐
- C++使用回溯算法解决简单迷宫问题
- c++实验3-多分段函数求值
- c++第三次实验(定期存款利息计算器)
- C语言小问题记录
- c++实验三--个人所得税计算器
- C++作业3
- 【使用CMake组织C++工程】2:CMake 常用命令和变量
- C 【进制查表法 求取给定十进制数的其他进制形式数值】
- C++实验3-1-个人所得税计算器
- 作业:C++作业3
- Worktile 移动团队如何使用 C++ 完成跨平台应用开发
- emacs中完成c++程序编译执行
- C++ Primer 5th - 2.1 基础内建类型
- C/C++拷贝文件的方法
- VS2010的C++项目属性
- c++作业03
- c++第三次实验-1
- c++第三次实验-1
- c++第三次实验作业
- c++实验三-计算税收及收入