一 说明
(1)应用情况:比如基于socket来实现http协议等,这时候就需要解析URL。
(2)为了移植性,没有用非标准C库windows下的StrDup(linux下为strdup),用自己编写的dup_str。
(3)编译环境:windows ,visual studio2010
二 URL的格式:
(协议)://(主机名):(端口号) / (文件路径)/(文件名)
例如:http://zj.qq.com/a/20130824/002507.htm#p=8
http://www.itpub.net/kwrss/201211/wangzhiduankou.shtml
三 实现
#include <stdio.h> //printf #include <string.h> //strchr strncmp ,memcpy #include <malloc.h> //malloc free #include <stdlib.h> //atoi //将source开始空间的以NULL结尾的字符拷贝到dest中 //返回的指针需要free char*dup_str(const char*source) { if(source==NULL) return NULL; int len = strlen(source); char *dest = (char*)malloc(len+1); memcpy(dest,source,len+1); return dest; } //函数功能:解析URL //参数:host带回主机字符串,protocl协议,port端口,abs_path带回绝对路径 //使用完注意释放host和abs_path在堆上分配的内存 //备注:(1)先取到URL的一份拷贝,方面将该字符串截成几段,分别处理; // (2)用了指针引用,也可以使用二重指针来解决参数带回值的问题 void parse_URL(const char*URL,const char*protocl,char*&host,unsigned int &port,char*&abs_path) { if(URL == NULL) return ; char *url_dup = dup_str(URL); char *p_slash = NULL;//主机后第一个斜杠的位置 char *p_colon = NULL;//主机后第一个冒号的位置 char *start = 0; //记录www开始的位置 if(strncmp(url_dup,protocl,strlen(protocl))==0) { start = url_dup+strlen(protocl)+3; p_slash = strchr(start,'/'); if(p_slash != NULL) { abs_path= dup_str(p_slash); *p_slash = '\0'; } else { abs_path= dup_str("/"); } p_colon = strchr(start,':'); if(p_colon != NULL) { port = atoi(p_colon+1); *p_colon = '\0'; } else port = 8080;//没有的话取默认的8080端口 } host = dup_str(start); } if(url_dup != NULL) { free(url_dup); url_dup = NULL; } } int main() { //这是一个伪造的地址,用于测试 //char *URL = "http://www.xyz2013.com"; //char *URL = "ftp://www.xyz2013.com:8080"; char *URL = "https://www.xyz2013.com:1324/My/5201449.shtml"; char*abs_path = NULL; char*host = NULL; unsigned int port; parse_URL(URL,"https",host,port,abs_path); printf("主机地址:%s\n",host); printf("端口号:%d\n",port); printf("绝对路径:%s\n",abs_path); //需要释放host,abs_path if(host!=NULL) { free(host); host = NULL; } if(abs_path!=NULL) { free(abs_path); abs_path=NULL; } getchar(); }
结果: