argz_create函數

函數位於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輸出不顯示的結果。

相關文章
相關標籤/搜索