首页 > 其他 > 详细

argz_create_sep函数

时间:2015-09-29 23:41:46      阅读:726      评论:0      收藏:0      [点我收藏+]

函数位于glibc源码中的../glibc-version/string/argz-ctsep.c中,其作用是将字符串以指定的字符进行分割,指定字符的位置替换成空字符串(\0),使整个字符串形成一个argz vector。

argz vector是存储在连续空间的一维字符数组,彼此之间以空字符(\0)进行分隔。

也就是说argz_create_sep函数的目的是将一个字符串按指定字符分割成多个字符串,存入一个连续空间中,彼此之间以空字符(\0)进行分隔,形成argz vector。

函数声明如下:

// argz.h
/* Make a ‘\0‘ separated arg vector from a SEP separated list in
   STRING, returning it in ARGZ, and the total length in LEN.  If a
   memory allocation error occurs, ENOMEM is returned, otherwise 0.
   The result can be destroyed using free.  */
extern error_t __argz_create_sep (const char *__restrict __string,
								int __sep, char **__restrict __argz,
								size_t *__restrict __len) __THROW;
extern error_t argz_create_sep (const char *__restrict __string,
								int __sep, char **__restrict __argz,
								size_t *__restrict __len) __THROW;
/* */

函数的实现如下:

error_t
__argz_create_sep (const char *string, int delim, char **argz, size_t *len)
{
    size_t nlen = strlen (string) + 1;
    if (nlen > 1)
    {
        const char *rp;
        char *wp;
        *argz = (char *) malloc (nlen);
        if (*argz == NULL)
            return ENOMEM;
        rp = string;
        wp = *argz;
        do
            if (*rp == delim)
            {
                if (wp > *argz && wp[-1] != ‘\0‘)
                    *wp++ = ‘\0‘;
                else
                    --nlen;
            }
            else
                *wp++ = *rp;
        while (*rp++ != ‘\0‘);
        if (nlen == 0)
        {
            free (*argz);
            *argz = NULL;
            *len = 0;
        }
        *len = nlen;
    }
    else
    {
        *argz = NULL;
        *len = 0;
    }
    return 0;
}
weak_alias (__argz_create_sep, argz_create_sep)
/* */

代码相对比较简单,逐字符进行复制,遇到与delim相同的就替换成\0,然后继续复制。

需要注意的是下面这句。这段主要是针对特殊情况的处理。

1、待分割字符串string的第一个字符就是delim相同

2、待分割字符串string全部由delim构成

if (wp > *argz && wp[-1] != ‘\0‘)
    *wp++ = ‘\0‘;
else
    --nlen;
/* */

 

 调用__argz_create_sep函数的方式为:

const char *mystring = "string microsoft";
char delim = ‘s‘;
__argz_create_sep(mystring, delim, &argz, &len);
/* */

 

写个程序测试一下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ENOMEM  12

#ifndef __error_t_defined
typedef int error_t;
#endif

error_t __argz_create_sep (const char *string, int delim, char **argz, size_t *len)
{
    size_t nlen = strlen (string) + 1;
    if (nlen > 1)
    {
        const char *rp;
        char *wp;
        *argz = (char *) malloc (nlen);
        if (*argz == NULL)
            return ENOMEM;
        rp = string;
        wp = *argz;
        do
            if (*rp == delim)
            {
                if (wp > *argz && wp[-1] != ‘\0‘)
                    *wp++ = ‘\0‘;
                else
                    --nlen;
            }
            else
                *wp++ = *rp;
        while (*rp++ != ‘\0‘);
        if (nlen == 0)
        {
            free (*argz);
            *argz = NULL;
            *len = 0;
        }
        *len = nlen;
    }
    else
    {
        *argz = NULL;
        *len = 0;
    }
    return 0;
}

int main(void)
{
    int i;
    size_t len;
    char *argz = NULL;
    char delim = ‘s‘;
    const char *mystring = "string microsoft";
    __argz_create_sep(mystring, delim, &argz, &len);
    puts(argz);
    for(i=0; i<len; ++i){
        putchar(argz[i]);
    }
    putchar(‘\n‘);
    free(argz);
    return 0;
}

 程序输出如下:

技术分享

 

附:我觉得那个函数写的太蛋疼了。。果然我还是喜欢用for啊。。。

error_t __argz_create_sep (const char *string, int delim, char **argz, size_t *len)
{
	size_t nlen = strlen (string) + 1;
	const char *rp;
	char *wp;

	if(nlen <= 1)
	{
		*argz = NULL;
		len = 0;
		return 0;
	}

	*argz = (char *) malloc (nlen);
	if (*argz == NULL)	return ENOMEM;

	for(rp = string, wp = *argz; *rp; ++rp)
	{
		if(*rp == delim)
		{
			if(wp > *argz && wp[-1] != ‘\0‘){
				*wp++ = ‘\0‘;
			}
			else{
				--nlen;
			}
		}
		else{
			*wp++ = *rp;
		}
	}

	if (nlen == 0)
	{
		free (*argz);
		*argz = NULL;
	}
	*len = nlen;
	return 0;
}

argz_create_sep函数

原文:http://my.oschina.net/saiy/blog/512511

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!