- ngx_str_t定义
ngx_str_t是nginx中定义的类似于字符串的结构,其中包含了字符串的长度(不包含终止字符'\0')以及字符串的首地址,数据结构定义如下:
- typedef struct {
- size_t len;
- u_char *data;
- } ngx_str_t;
- 操作函数
1、初始化或赋值函数
- #define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
- #define ngx_null_string { 0, NULL }
- #define ngx_str_set(str, text) \
- (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
- #define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
- ngx_string(str)用于接受一个常量字符串数据,然后将该字符串的长度以及首地址传给ngx_str_t的结构体。
- ngx_null_string定义一个字符长度为0的结构体
- ngx_str_set用于将结构体ngx_str_t的长度以及首地址赋值为text的长度以及首地址。
- ngx_str_null(null)用于将结构体ngx_str_t初始化为长度为0,首地址为空的初始序列。
- ngx_str_set传入的是结构体的地址,因为下面的引用成员变量的方式是以指针的方式进行的,ngx_str_null亦是如此。
- ngx_str_t s1=ngx_null_string;
- ngx_str_t s2=ngx_string("hello nginx");
- ngx_str_set(&s2,"hello again hello");
- ngx_str_null(&s2);
2、字符处理函数
很多是封装的c下面的string.h文件中的函数:
- #define ngx_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c) //转小写字符
- #define ngx_toupper(c) (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c) //转大写字符
- void ngx_strlow(u_char *dst, u_char *src, size_t n); //从src复制n个字符到dst中,同时将相应的字符转为小写字符
- #define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n) //字符比较函数,只比较前面n个字符,大小写敏感
- #define ngx_strcmp(s1, s2) strcmp((const char *) s1, (const char *) s2) //字符比较函数,一直到某个字符的终止位置,大小写敏感
- #define ngx_strstr(s1, s2) strstr((const char *) s1, (const char *) s2) //查找子串
- #define ngx_strlen(s) strlen((const char *) s) //计算字符穿长度
- #define ngx_strchr(s1, c) strchr((const char *) s1, (int) c) //第一次出现c的位置
自定义函数:
比较函数:
- ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);
- ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n); //以上两个函数类似与ngx_strcmp,ngx_strncmp,大小写不敏感
格式打印函数:
- u_char * ngx_cdecl ngx_sprintf(u_char *buf, const char *fmt, ...);
- u_char * ngx_cdecl ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);
- u_char * ngx_cdecl ngx_slprintf(u_char *buf, u_char *last, const char *fmt,
ngx_cdecl是一个宏定义,原型为_cdecl,表示函数的参数从从右到左依次入账,是默认的函数调用方法,用到这个是因为以上三个参数用到了省略号参数,参数个数是可变的。以ngx_snprintf为例进行讲解:
- u_char * ngx_cdecl
- ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
- {
- u_char *p;
- va_list args;
- va_start(args, fmt);
- p = ngx_vslprintf(buf, buf + max, fmt, args);
- va_end(args);
- return p;
- }
对于 va_list, va_start以及 va_end的讲解,请参考改博客内容: http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html对于可变参数列表,一般有以下几个步骤:
- 在调用参数表之前,定义一个 va_list 类型的变量,(假设va_list 类型变量被定义为ap);
- 然后应该对ap 进行初始化,让它指向可变参数表里面的第一个参数,这是通过 va_start 来实现的,第一个参数是 ap 本身,第二个参数是在变参表前面紧挨着的一个变量,即“...”之前的那个参数;
- 然后是获取参数,调用va_arg,它的第一个参数是ap,第二个参数是要获取的参数的指定类型,然后返回这个指定类型的值,并且把 ap 的位置指向变参表的下一个变量位置;
- 获取所有的参数之后,我们有必要将这个 ap 指针关掉,以免发生危险,方法是调用 va_end,他是输入的参数 ap 置为 NULL,应该养成获取完参数表之后关闭指针的习惯。说白了,就是让我们的程序具有健壮性。通常va_start和va_end是成对出
在ngx_snprintf中,fmt是可变参数,我们都知道,printf里面会有"%d%d%s"这种类似的格式,那么这里的fmt也是一样的。ngx_snprintf的格式参数包含:
- /*
- * supported formats:
- * %[0][width][x][X]O off_t
- * %[0][width]T time_t
- * %[0][width][u][x|X]z ssize_t/size_t
- * %[0][width][u][x|X]d int/u_int
- * %[0][width][u][x|X]l long
- * %[0][width|m][u][x|X]i ngx_int_t/ngx_uint_t
- * %[0][width][u][x|X]D int32_t/uint32_t
- * %[0][width][u][x|X]L int64_t/uint64_t
- * %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t
- * %[0][width][.width]f double, max valid number fits to %18.15f
- * %P ngx_pid_t
- * %M ngx_msec_t
- * %r rlim_t
- * %p void *
- * %V ngx_str_t *
- * %v ngx_variable_value_t *
- * %s null-terminated string
- * %*s length and string
- * %Z '\0'
- * %N '\n'
- * %c char
- * %% %
- *
- * reserved:
- * %t ptrdiff_t
- * %S null-terminated wchar string
- * %C wchar
- */
以上三个函数都调用了函数:
- u_char *ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args);
复制函数
- u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n);
- u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src);
- #include <ngx_config.h>
- #include <ngx_core.h>
- #include<ngx_string.h>
- int main(int args,char *argv[])
- {
- u_char *p;
- ngx_str_t str = ngx_null_string;
- unsigned char buffer[1024];
- printf("str長度爲:%d\n",(int)str.len);
- ngx_str_set(&str,"hello world"); //注意是&str而不是str
- p=ngx_snprintf(buffer, str.len, "%V", &str); //注意是&str而不是str
- buffer[str.len]='\0';
- printf("格式化str輸出爲:%s\n",buffer);
- printf("格式化長度爲:%d\n",(int)((p-buffer)/sizeof(char))); //p返回的是最後輸出的位置,所以由此可以得出最後格式化的字符個數
- return 1;
- }
转自:http://blog.csdn.net/mao19931004/article/details/54341062