函數位於glibc源碼中的../glibc-version/string/argz-create.c中,其做用是將Unix-style的參數數組argv轉換成一個argz vector。linux
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;
函數的實現以下:unix
/* 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的方式應當以下:rest
char *argz = NULL; size_t len; argz_create(argv, &argz, &len);
stpcpy函數(__stpcpy)在/usr/include/string.h中進行聲明。code
源碼位於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; }
程序輸出以下:
注意,輸出結果中字符串之間的「空格」並非空格,而是\0輸出不顯示的結果。