细究代码之——dirname实现

开发中一部分工作是编写服务端的功能库,经常需要用到类似于Linux上dirname的功能。

先贴出第一个版本:

#define IS_SLASH_P(c)  (*(c) == '/' || *(c) == '\\')
//对于合法的路径输入,返回其上一级目录,不包含目录分隔符
//返回值为pcDir的长度
int lib_iDirName(const char *path, char *pcDir)
{
	int len = 0;
	const char *endp = NULL;
	const char *runp = NULL;
	
	*pcDir = '\0';
	if(path == NULL || *path == '\0')
	{
		return len;
	}
	
	runp = path+strlen(path)-1;
	while(runp > path && IS_SLASH_P(runp))--runp;
	if(runp == path)
	{
		endp = path;
	}
	else
	{
		while(runp > path && !IS_SLASH_P(runp))--runp;
		if(runp == path)
		{
			endp = path;
		}
		else
		{
			while(runp > path && IS_SLASH_P(runp))--runp;
			endp = runp;
		}
	}
	
	if (endp != path)
    {
		len = endp-path+1;
		memcpy(pcDir, path, len);
		pcDir[len] = '\0';
    }
	else
	{
		if(*path == '/')//for Linux
		{
			strcpy(pcDir, "/");
			len = 1;
		}
		else if(path[1] == ':')//for Windows
		{
			memcpy(pcDir, path, 2);
			pcDir[2] = '\0';
			len = 2;
		}
		else
		{
			strcpy(pcDir, ".");
			len = 1;
		}
	}
	return len;
}

实现上涉及到对目录分割符的处理,若对这一块内容有疑问,可以参考我另外一篇短文:细说目录分隔符

测试结果:



这个结果已经符合我的预期了,但是里面3个while(runp > path ...)感觉是可以合在一块儿的,于是有了下一个“增强”版本:

int lib_iDirNameEx(const char *path, char *pcDir)
{
	int len = 0;
	int count = 0;
	const char *runp = NULL;

	*pcDir = '\0';
	if(path == NULL || *path == '\0')
	{
		return len;
	}

	runp = path+strlen(path)-1;
	while(runp > path)
	{
		if(IS_SLASH_P(runp))
		{
			--runp;
			continue;
		}
		if(count >= 1)break;
		if(!IS_SLASH_P(runp))
		{
			--runp;
		}
		if(IS_SLASH_P(runp))
		{
			count++;
		}
	}

	if (runp != path)
    {
		len = runp-path+1;
		memcpy(pcDir, path, len);
		pcDir[len] = '\0';
    }
	else
	{
		if(*path == '/')//for Linux
		{
			strcpy(pcDir, "/");
			len = 1;
		}
		else if(path[1] == ':')//for Windows
		{
			memcpy(pcDir, path, 2);
			pcDir[2] = '\0';
			len = 2;
		}
		else
		{
			strcpy(pcDir, ".");
			len = 1;
		}
	}
	return len;
}
如果
if(count >= 1)break;
这一行改成

if(count >= 2)break;
可以实现回退两级目录,以此类推。暂时就这样定版了!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值