定義
strsep函式char *strsep(char **stringp, const char *delim);
功能及用法
分解字元串為一組字元串。從stringp指向的位置起向後掃描,遇到delim指向的字元串中的字元後,將此字元替換為NULL,返回stringp指向的地址。它適用於分割“關鍵字”在兩個字元串之間只“嚴格出現一次”的情況。 如果“關鍵字”在字元串之間連續出現,可使用如下技巧解決:
char str[] = "abcdefg";
char *p = str;
char *key_point;
while(p)
{
while ( key_point = strsep(&p,"cd"))//關鍵字為c或d,它們連續出現了
{
//函式遇到c時,key_point指向c返回,遇到d時key_point指向d返回(注意此時d已經被改寫為'\0'了)
if (*key_point == 0)
continue;//遇到連續的關鍵字,返回一個指向\0的指針,繼續往後找就是
else
break;//分割出一個正常的字元串,快去列印吧!
}
printf("%s\n",key_point);
}
strsep函式,這在 Windows Dev-C++ 是沒有支持的,在寫UNIX分析字元串常常需要利用到此函式,大家可以 man strsep來看如何使用 strsep,假設我們要分析 URLGet 字元串: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 的原始碼:
上面程式代碼可以看到 stringp 如果為 NULL 就回傳 NULL,接下來進行每一個字的比對,如果發現到有 delim,如果是在字元串結尾符號 \0,則將字元串設定為 NULL 並且更新 stringp,如果並非字元串結尾,就將字元串(s)往前一個(delim 符號),並且將其改變為 \0 分割點,且更新 *stringp 指向 delim 符號下一個字,回傳初始字元串。
示例
例一
底下來分析 username=appleboy&password=1234∾tion=delete字元串,程式代碼如下:
裡面大家可以看一下 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\n", 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(≠xt,"&"); // 這時通過"&"分割字元串,返回值為100,next指 向"maxMtu=200"
printf(" name= %s\n",name); //列印出一輪分割後name的值
printf("value= %s\n",value);
value=next;
}
}
執行結果為:
name= Number
value= 100
name= maxMtu
value= 200