词条 | strsep |
释义 | 原型:char *strsep(char **stringp, const char *delim); 功能:分解字符串为一组字符串。从stringp指向的位置起向后扫描,遇到delim指向位置的字符后,将此字符替换为NULL,返回stringp指向的地址。 strsep函数,这在 Windows Dev-C++ 是没有支持的,在写 UNIX 分析字符串常常需要利用到此函式,大家可以 man strsep来看如何使用 strsep,假设我们要分析 URL Get 字符串:user_command=appleboy&test=1&test2=2,就可以利用两次 strsep 函式,将字符串全部分离,取的个别的 name,value。strsep(stringp,delim) 第一个参数传入需要分析的字符串,第二个参数传入 delim 符号,假设 stringp 为 NULL 字符串,则函式会回传 NULL,换句话说,strsep 会找到 stringp 字符串第一个出现 delim 符号,并将其取代为 \\0 符号,然后将 stringp 更新指向到 \\0 符号的下一个字符串,strsep() function 回传原来的 stringp 指标。看上面文字叙述,好像不太了解,没关系,底下是 UNIXstrsep.c 的原始码: /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no moretokens). * * If *stringp is NULL, strsep returns NULL. */ char *strsep(char **stringp, const char *delim) { char *s; const char *spanp; int c, sc; char *tok; if ((s = *stringp)== NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc =*spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } 上面程序代码可以看到 stringp 如果为 NULL 就回传 NULL,接下来进行每一个字的比对,如果发现到有 delim,如果是在字符串结尾符号 \\0,则将字符串设定为 NULL 并且更新 stringp,如果并非字符串结尾,就将字符串(s)往前一个(delim 符号),并且将其改变为 \\0 分割点,且更新 *stringp 指向 delim 符号下一个字,回传初始字符串。 底下来分析 username=appleboy&password=1234&action=delete字符串,程序代码如下:/* * * Author : appleboy * Date : 2010.04.27 * Filename : strsep.c * */ int main() { int len, nel; char query[] ="user_command=appleboy&test=1&test2=2"; char *q, *name, *value; /* Parse into individualassignments */ q = query; fprintf(stderr, "CGI[query string] : %s\",query); len = strlen(query); nel = 1; while (strsep(&q, "&")) nel++; fprintf(stderr, "CGI[nel string] : %d\", nel); for (q = query; q< (query + len);) { value = name = q; /* Skip to next assignment */ fprintf(stderr, "CGI[string] :%s\", q); fprintf(stderr, "CGI[stringlen] : %d\", strlen(q)); fprintf(stderr, "CGI[address] :%x\", q); for (q += strlen(q); q < (query +len) && !*q; q++); /* Assign variable */ name = strsep(&value,"="); fprintf(stderr, "CGI[name ] :%s\", name); fprintf(stderr, "CGI[value] :%s\", value); } return 0; } 里面大家可以看一下 while (strsep(&q,“&”)) 这边,这是利用 & 符号切割字符串,并且算出有几个符合,底下再把 q 重新指向 query,跑 for 循环,要小于字符串长度,由于已经经过一次 strsep 函式,所以全部的 & 符号都取代成 \\0,整体字符串变成user_command=appleboy\\0test=1\\0test2=2,故执行到 for (q += strlen(q); q < (query + len)&& !*q; q++);,会将 q 指标指向 test=1 的 t 字母,底下在 name = strsep(&value,“=”); 将原本的user_command=appleboy 分割,所以 name 输出 user_command,value 输出 appleboy,大致上是这样。 输出结果: CGI[query string] :user_command=appleboy&test=1&test2=2 CGI[nel string] : 4 CGI[string] : user_command=appleboy CGI[string len] : 21 CGI[address] : bfb537b0 CGI[name ] : user_command CGI[value] : appleboy CGI[string] : test=1 CGI[string len] : 6 CGI[address] : bfb537c6 CGI[name ] : test CGI[value] : 1 CGI[string] : test2=2 CGI[string len] : 7 CGI[address] : bfb537cd CGI[name ] : test2 CGI[value] : 2 示例二: #include <stdio.h> #include <string.h> int main(void) { char str[] = "root:x::0:root:/root:/bin/bash:"; char *buf; char *token; buf = str; while((token = strsep(&buf, ":")) != NULL){ printf("%s\", token); } return 0; } 再一个示例程序: #include <stdio.h> #include <string.h> void main() { char str[]="Number=100&maxMtu=200"; char *name,*value,*next; int i; value=str; //使指针value 指向字符串str; for(i=0 ;i<2 ;i++) { // 第一次执行时 name = strsep(&value,"="); // 以"="分割字符串,这时strsep函数返回值为 "Number",即"="号之前的字符串 next =value; // 这时指针value指向"="号后面的字符串,即"100&maxMtu=200" value=strsep(&next,"&"); // 这时通过"&"分割字符串,返回值为100,next指 向"maxMtu=200" printf(" name= %s\",name); //打印出一轮分割后name的值 printf("value= %s\",value); value=next; } } 执行结果为: name= Number value= 100 name= maxMtu value= 200 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。