argz_create函数

函数位于glibc源码中的../glibc-version/string/argz-create.c中,其作用是将Unix-style的参数数组argv转换成一个argz vector。

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

也就是说argz_create函数的目的是将二维的argv转换成一维数组,并且内容不变,保留\0作为字符串之间的分隔符。

函数声明如下:

// argz.h
/* Make a '\0' separated arg vector from a unix argv vector, 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 (char *const __argv[], char **__restrict __argz,
                              size_t *__restrict __len) __THROW;
extern error_t argz_create (char *const __argv[], char **__restrict __argz,
                            size_t *__restrict __len) __THROW;

 函数的实现如下:

/* Make a '\0' separated arg vector from a unix argv vector, returning it in
   ARGZ, and the total length in LEN.  If a memory allocation error occurs,
   ENOMEM is returned, otherwise 0.  */
error_t
__argz_create (char *const argv[], char **argz, size_t *len)
{
    int argc;
    size_t tlen = 0;
    char *const *ap;
    char *p;
    for (argc = 0; argv[argc] != NULL; ++argc)
        tlen += strlen (argv[argc]) + 1;
    if (tlen == 0)
        *argz = NULL;
    else
    {
        *argz = malloc (tlen);
        if (*argz == NULL)
            return ENOMEM;
        for (p = *argz, ap = argv; *ap; ++ap, ++p)
            p = __stpcpy (p, *ap);
    }
    *len = tlen;
    return 0;
}
weak_alias (__argz_create, argz_create)

需要注意的是,char *argv[]是main函数参数中的二维数组,它是以NULL作为结束标志的,即argv[argc]=NULL,所以程序可以使用argv[argc] != NULL进行判断,而普通的二维数组是不符合这一特点的。由此,程序可以求得整个argv(包括\0在内)在一维上的长度。

 

调用argz_create的方式应当如下:

char *argz = NULL;
size_t len;
argz_create(argv, &argz, &len);

 

stpcpy函数(__stpcpy)在/usr/include/string.h中进行声明。

源码位于glibc源码中的../glibc-version/string/stpcpy.c文件中。

具体定义如下:

/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
char *__stpcpy (char *dest, const char *src)
{
    size_t len = strlen (src);
    return memcpy (dest, src, len + 1) + len;
}

正如注释中所说,stpcpy函数返回的是返回指向dest结尾处字符('\0')的指针。

注意:stpcpy函数不是标准库中的函数,只有glibc中有。

 

写个程序测试一下:

/* Windows(R) 7, Ultimate edition
   CodeBlocks13.12
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ENOMEM  12

#ifndef __error_t_defined
typedef int error_t;
#endif

/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
char *__stpcpy (char *dest, const char *src)    // linux系统中可以不添加该函数
{
  size_t len = strlen (src);
  return memcpy(dest, src, len + 1) + len;
}

error_t __argz_create(char *const argv[], char **argz, size_t *len)
{
    int argc;
    size_t tlen = 0;
    char *const *ap;
    char *p;
    for (argc = 0; argv[argc] != NULL; ++argc){
        tlen += strlen (argv[argc]) + 1;
    }
    if (tlen == 0)
        *argz = NULL;
    else
    {
        *argz = malloc(tlen);
        if (*argz == NULL)
            return ENOMEM;
        for (p = *argz, ap = argv; *ap; ++ap, ++p)
            p = __stpcpy (p, *ap);
    }
    *len = tlen;
    return 0;
}

int main(void)
{
    int i;
    char *argv[6] = {
        "vector creating using these fu",
        "nctions may be fre",
        "ed by using free; conversely, any argz",
        "function that may grow a ",
        "string expects that string to have been all",
        NULL
    };
    char *argz = NULL;
    size_t len;
    if(__argz_create(argv, &argz, &len)){
        printf("error!\n");
        return 1;
    }
    for(i=0; i<len; ++i){
        putchar(argz[i]);
    }
    putchar('\n');
    return 0;
}

程序输出如下:

 151641_HBmR_143971.png

注意,输出结果中字符串之间的“空格”并不是空格,而是\0输出不显示的结果。

转载于:https://my.oschina.net/saiy/blog/512327

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值