函数位于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#include #include #define ENOMEM 12#ifndef __error_t_definedtypedef 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
程序输出如下:
注意,输出结果中字符串之间的“空格”并不是空格,而是\0输出不显示的结果。