解析文件路径 Myth丶恋晨 2022-06-18 04:44 188阅读 0赞 有时候在编程时会碰到文件路径的解析,如提取一个文件路径中的文件名、文件所在目录,文件的后缀名等。下面写了一个小函数以实现这些功能。 #include <stdio.h> #include <string.h> typedef struct file_pathname{ char mini_pathname[1024]; /*文件的路径和名字(不带扩展名)*/ char fdir[1024]; /*文件所在的目录*/ char mini_fname[256]; /*文件的名字(不带扩展名)*/ char suffix[30]; /*文件的扩展名*/ }fpn; fpn *analysis_pathname(fpn *myfpn, char *pathname); int main() { fpn fpn_log; memset(&fpn_log, 0, sizeof(fpn)); analysis_pathname(&fpn_log, "/root/home/Rayin/abc.log"); printf("文件的路径和名字(不带扩展名):%s\n",fpn_log.mini_pathname); printf("文件所在的目录:%s\n",fpn_log.fdir); printf("文件的名字(不带扩展名):%s\n",fpn_log.mini_fname); printf("文件的扩展名:%s\n",fpn_log.suffix); } /* *解析文件路径,提取出文件所在的目录、文件名和扩展名 *成功返回存放以上信息的结构体指针,失败返回NULL */ fpn *analysis_pathname(fpn *myfpn, char *pathname) { int len; int i, j, k, rear; i = j = k = rear = 0; len = strlen(pathname); if (!pathname) return NULL; i = len - 1; while (pathname[i] != '.' && i >= 0) { i--; } if (i == len -1 || i < 0) { printf("log file:no suffix name!\n"); i = rear = len -1; /*无扩展名,i和rear都指向文件名最后一个字符的下标 */ } else { for (rear = i; rear < len; rear++) { /*有扩展名*/ myfpn->suffix[j++] = pathname[rear]; } i--; rear = i; /*i和rear都指向文件名最后一个字符的下标 */ myfpn->suffix[j] = '\0'; j = 0; } while (pathname[i] != '/' && i >= 0) { /*最后一个"/"是路径与文件名格开的标记*/ i--; } if (i == rear) { printf("pathname error:no file name!\n"); /*没有文件名*/ return NULL; } if (i == -1) { printf("pathname error:no dir!\n"); /*没有目录*/ return NULL; } while (j <= rear) { if (j <= i) { myfpn->fdir[j] = pathname[j]; /*提取文件所在目录(最里层)*/ j++; } else { if (j <= rear) { /*仅提取文件名,不含扩展名*/ myfpn->mini_fname[k++] = pathname[j++]; } else break; } } myfpn->fdir[j] = '\0'; /*文件所在目录*/ myfpn->mini_fname[k] = '\0'; /*文件名,不含扩展名*/ strcpy(myfpn->mini_pathname, myfpn->fdir); strcat(myfpn->mini_pathname, myfpn->mini_fname);/*提取文件的路径和名字(不带扩展名)*/ return myfpn; } 结果: 文件的路径和名字(不带扩展名):/root/home/Rayin/abc 文件所在的目录:/root/home/Rayin/ 文件的名字(不带扩展名):abc 文件的扩展名:.log 最近又看了看这个,感觉还是有些不足,如,结构体fpn的成员有些多余,这样放浪内存空间,analyse\_pathname()函数看起结构和逻辑都很复杂,下面出一个改良版本。有不足的地方,请多指正。 #include <stdio.h> #include <string.h> typedef struct file_pathname{ char fdir[256]; /*文件所在的目录*/ char mini_fname[256]; /*文件的名字(不带扩展名)*/ char suffix[10]; /*文件的扩展名*/ }fpn_t; int strpos(const char *src, char c, int flag); fpn_t *analysis_pathname(fpn_t *myfpn, char *pathname); int main() { fpn_t myfpn; memset(&myfpn, 0, sizeof(fpn_t)); if (NULL != analysis_pathname(&myfpn, "./apple.log")) { printf("%s\n",myfpn.fdir); printf("%s\n",myfpn.mini_fname); printf("%s\n",myfpn.suffix); } else printf("error!\n"); } /* 功能:解析文件路径,提取出文件所在的目录、文件名和扩展名 * 参数:myfpn,存放以上信息的结构体指针;pathname,文件路径 * 返回值:成功为fpn_t *,失败为NULL. */ fpn_t *analysis_pathname(fpn_t *myfpn, char *pathname) { int i, pos, j; i = pos = j = 0; if (!pathname) return NULL; /* 获取文件所在的目录fdir */ pos = strpos(pathname, '/', 1); //标志为1表示从尾部开始找 if (pos == -1) return NULL; while(i < pos) { myfpn->fdir[i] = pathname[i]; i++; } myfpn->fdir[i] = '\0'; /* 获取文件的名字(不带扩展名)mini_fname */ i = strpos(pathname, '/', 1); pos = strpos(pathname, '.', 1); if (i == -1 || pos == -1) return NULL; pos--; while(i < pos) { myfpn->mini_fname[j] = pathname[i]; i++; j++; } myfpn->mini_fname[j] = '\0'; /* 获取文件的扩展名suffix,即.xxx */ i = strpos(pathname, '.', 1); pos = strlen(pathname); if (i == pos) //没有后缀 return NULL; i--; j = 0; while(i < pos) { myfpn->suffix[j] = pathname[i]; i++; j++; } myfpn->suffix[j] = '\0'; return myfpn; } /* 功能:获取某字符c,在字符串src中的位置 * 参数:src,源字符串;c,字符;flag,选择查找顺序的标志,0表示从头部开始找,1表示从尾部开始找 * 返回值:成功为字符c在字符串src中的实际位置,范围:[1,strlen];失败为-1。 */ int strpos(const char *src, char c, int flag) { const char *p; int pos, len; p = src; pos = 1; len = strlen(src); if (flag == 0) { //flag == 0表示从头部开始找 while (c != *p && *p) { pos++; p++; } if(*p == '\0') //没有此字符 pos = -1; } else if(flag == 1) { //flag == 1表示从尾部开始找 p += len -1; //指向字符串的最后一个字符 pos = len; while (c != *p && pos > 0) { pos--; p--; } if(pos == 0) //没有此字符 pos = -1; } return pos; //返回字符c在字符串src中的实际位置,范围:[1,strlen];失败为-1. } 这里多了一个函数int strpos(const char \*src, char c, int flag),使得fpn\_t \*analysis\_pathname(fpn\_t \*myfpn, char \*pathname)的结构和逻辑更加简洁明了。 结果: ./ apple .log =========================== 第三次优化:大内存结构体变量不宜分配在栈上,因为栈空间本身就比较小,而应该用堆分配,并且按需分配内存。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct file_pathname{ char *fdir; /*文件所在的目录*/ char *mini_fname; /*文件的名字(不带扩展名)*/ char *suffix; /*文件的扩展名*/ }fpn_t; int strpos(const char *src, char c, int flag); fpn_t *analysis_pathname(char *pathname); void release_fpn(fpn_t *fpn); int main() { fpn_t *myfpn = NULL; //定义后一定要赋初值为NULL;且要记得最后释放它所指向的空间 if (NULL != (myfpn = analysis_pathname("/home/lgh/apple.log"))) { printf("%s\n", myfpn->fdir); printf("%s\n", myfpn->mini_fname); printf("%s\n", myfpn->suffix); } else printf("error!\n"); release_fpn(myfpn); return 0; } /* 功能:解析文件路径,提取出文件所在的目录、文件名和扩展名, * 这些信息都是按需分配内存空间。使用完后记得释放该函数分配的内存空间。 * 参数:pathname,文件路径. * 返回值:成功为fpn_t *,失败为NULL. */ fpn_t *analysis_pathname(char *pathname) { int i, pos, j; fpn_t *fpn; i = pos = j = 0; fpn = NULL; if (!pathname) return NULL; fpn = (fpn_t *)malloc(sizeof(fpn_t)); if (fpn) memset(fpn, 0, sizeof(fpn_t)); else return NULL; /* 获取文件所在的目录fdir */ pos = strpos(pathname, '/', 1); //标志为1表示从尾部开始找 if (pos == -1) return NULL; else { //分配空间 fpn->fdir = (char *)malloc(sizeof(char)*(pos+1)); if (fpn->fdir) memset(fpn->fdir, 0, sizeof(char)*(pos+1)); else return NULL; } while(i < pos) { fpn->fdir[i] = pathname[i]; i++; } fpn->fdir[i] = '\0'; /* 获取文件的名字(不带扩展名)mini_fname */ i = strpos(pathname, '/', 1); pos = strpos(pathname, '.', 1); if (i == -1 || pos == -1) return NULL; else { fpn->mini_fname = (char *)malloc(sizeof(char)*(pos-i)); if (fpn->mini_fname) memset(fpn->mini_fname, 0, sizeof(char)*(pos-i)); else return NULL; } pos--; while(i < pos) { fpn->mini_fname[j] = pathname[i]; i++; j++; } fpn->mini_fname[j] = '\0'; /* 获取文件的扩展名suffix,即.xxx */ i = strpos(pathname, '.', 1); pos = strlen(pathname); if (i == pos) //没有后缀 return NULL; else { fpn->suffix = (char *)malloc(sizeof(char)*(pos-i+1)); if (fpn->suffix) memset(fpn->suffix, 0, sizeof(char)*(pos-i+1)); else return NULL; } i--; j = 0; while(i < pos) { fpn->suffix[j] = pathname[i]; i++; j++; } fpn->suffix[j] = '\0'; return fpn; } /* 功能:获取某字符c,在字符串src中的位置(第一次出现,从开头或从尾部) * 参数:src,源字符串;c,字符;flag,选择查找顺序的标志,0表示从头部开始找,1表示从尾部开始找 * 返回值:成功为字符c在字符串src中的实际位置,范围:[1,strlen];失败为-1。 */ int strpos(const char *src, char c, int flag) { const char *p; int pos, len; p = src; pos = 1; len = strlen(src); if (flag == 0) { //flag == 0表示从头部开始找 while (c != *p && *p) { pos++; p++; } if(*p == '\0') //没有此字符 pos = -1; } else if(flag == 1) { //flag == 1表示从尾部开始找 p += len -1; //指向字符串的最后一个字符 pos = len; while (c != *p && pos > 0) { pos--; p--; } if(pos == 0) //没有此字符 pos = -1; } return pos; //返回字符c在字符串src中的实际位置,范围:[1,strlen];失败为-1. } void release_fpn(fpn_t *fpn) { if (fpn) { if (fpn->fdir) free(fpn->fdir); if (fpn->mini_fname) free(fpn->mini_fname); if (fpn->suffix) free(fpn->suffix); free(fpn); fpn = NULL; } } 结果: /home/lgh/ apple .log \-----------------------------------------------------------------------------------ending!
相关 文件路径解析错误:Java读写文件失败示例 在Java中,当我们尝试读写文件时,可能会遇到各种错误。下面是一些常见的错误示例: 1. **文件不存在错误**: ```java File file = new File( 野性酷女/ 2024年09月10日 09:33/ 0 赞/ 23 阅读
相关 HTML 文件路径 HTML 文件路径 HTML 脚本 HTML 头部 路径 描述 < img src=“picture.jpg”> picture.jpg 位于与当前网页相同的 「爱情、让人受尽委屈。」/ 2022年11月12日 01:39/ 0 赞/ 114 阅读
相关 Go——从文件路径解析解析GAVC坐标解决方案 源代码:https://gitee.com/shentuzhigang/mini-project/tree/master/go-gavc 解决方案 正则表达式来自:Ar 柔情只为你懂/ 2022年09月04日 06:46/ 0 赞/ 65 阅读
相关 webpack file-loader 解析 css 文件中 background-image路径问题。 webpack file-loader 解析 css 文件中 background-image路径问题。 通过 webpack 的 file-loader 把 css 中 不念不忘少年蓝@/ 2022年07月12日 01:17/ 0 赞/ 258 阅读
相关 解析文件路径 有时候在编程时会碰到文件路径的解析,如提取一个文件路径中的文件名、文件所在目录,文件的后缀名等。下面写了一个小函数以实现这些功能。 include <stdio.h Myth丶恋晨/ 2022年06月18日 04:44/ 0 赞/ 189 阅读
相关 eclipse运行时的文件路径与, 项目生成的.class路径解析的区别 > 我前前几天写一个Demo, 是关于一个桌面动漫的, 项目中有非常多的image文件. > 如下图 > ![项目图片][70] > > 然后把图片导入到java项目 蔚落/ 2022年05月23日 06:43/ 0 赞/ 142 阅读
相关 python 解析url路径 原理:使用urlparse,先解析整个url,然后使用split('/')方式构造为词典,下面就可以直接读取 from urllib.parse impor 一时失言乱红尘/ 2022年05月22日 23:44/ 0 赞/ 184 阅读
相关 通过LNK文件(快捷方式)解析出目标文件的路径 转载自:[https://blog.csdn.net/yoie01/article/details/8688686][https_blog.csdn.net_yoie01_ar 红太狼/ 2022年05月08日 11:44/ 0 赞/ 406 阅读
还没有评论,来说两句吧...