解析文件路径 Myth丶恋晨 2022-06-18 04:44 224阅读 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. **相对路径不明确**: 如果只是提供一个相对路径(如 `./file. 逃离我推掉我的手/ 2024年11月15日 04:00/ 0 赞/ 2 阅读
相关 解析实例:Java文件路径操作的常见问题 在Java编程中,文件路径操作是常见的任务。以下是一个关于Java文件路径操作的常见问题的示例解析: 问题描述: "我在Java中尝试读取一个特定目录下的所有文件,但代码总是 野性酷女/ 2024年10月12日 05:12/ 0 赞/ 40 阅读
相关 解析:Java中关于文件路径操作的常见问题 在Java编程中,处理文件路径是一个常见的任务。以下是一些在Java中处理文件路径操作时可能遇到的问题: 1. **路径不存在**: 如果试图访问的文件或目录不在指定路 客官°小女子只卖身不卖艺/ 2024年09月27日 08:30/ 0 赞/ 67 阅读
相关 常见错误解析:Java中文件路径拼写问题 在Java编程中,文件路径的拼写错误可能导致各种问题,如: 1. **找不到文件**:如果你在代码中试图读取一个不存在的文件,那么程序会抛出`FileNotFoundExce 梦里梦外;/ 2024年09月21日 08:18/ 0 赞/ 63 阅读
相关 文件路径解析错误:Java读写文件失败示例 在Java中,当我们尝试读写文件时,可能会遇到各种错误。下面是一些常见的错误示例: 1. **文件不存在错误**: ```java File file = new File( 野性酷女/ 2024年09月10日 09:33/ 0 赞/ 57 阅读
相关 Go——从文件路径解析解析GAVC坐标解决方案 源代码:https://gitee.com/shentuzhigang/mini-project/tree/master/go-gavc 解决方案 正则表达式来自:Ar 柔情只为你懂/ 2022年09月04日 06:46/ 0 赞/ 94 阅读
相关 解析文件路径 有时候在编程时会碰到文件路径的解析,如提取一个文件路径中的文件名、文件所在目录,文件的后缀名等。下面写了一个小函数以实现这些功能。 include <stdio.h Myth丶恋晨/ 2022年06月18日 04:44/ 0 赞/ 225 阅读
相关 python 解析url路径 原理:使用urlparse,先解析整个url,然后使用split('/')方式构造为词典,下面就可以直接读取 from urllib.parse impor 一时失言乱红尘/ 2022年05月22日 23:44/ 0 赞/ 226 阅读
相关 通过LNK文件(快捷方式)解析出目标文件的路径 转载自:[https://blog.csdn.net/yoie01/article/details/8688686][https_blog.csdn.net_yoie01_ar 红太狼/ 2022年05月08日 11:44/ 0 赞/ 429 阅读
还没有评论,来说两句吧...