117
技術社區[雲棲]
strtok:字符串分割函數
最近一直糾結於一個十分簡單的問題:如何將一個字符串按標誌分割開來?提出這個問題的初衷是自己在處理一個將命令行字符串轉換為argc,argv格式的問題。
嚐試了很多種方法,最後覺得利用strtok()函數來實現是一個比較好的方法。首先進行strtok()函數的介紹。
char *strtok(string, control);
--- Tokenize string with delimiter in control.
--- 通過分割符控製將字符串切片化。
Purpose:
strtok認為字符串是由一個或多個文本切片組成,這些文本切片被一個或多個字符分隔開來。第一次調用時,返回第一個文本切片的第一個字符指針,同時將該文本切片後的控製字符設為NULL。此後的調用重複上麵的操作,直到沒有文本切片首字符返回(返回NULL)為止。這些控製字符可能在不同的調用中而不同。當字符串中沒有文本切片時,則返回NULL。首次調用時,string指向要分解的字符串,之後再次調用要把string設成NULL。strtok在string中查找包含在delim中的字符並用NULL('/0')來替換,直到找遍整個字符串。
Entry:
char *string --- string to tokenize, or NULL to get next token
char *control --- string of characters to use as delimiters
Exit:
Return pointer to first token in string, or if string was NULL, to next token. Return NULL when no more tokens remain.
Source Code:
#include <string.h>
static char *olds;
/* Parse S into tokens separated by characters in DELIM. If S is NULL, the last string strtok() was called with is used. For example:
char s[] = "-abc-=-def";
x = strtok(s, "-"); // x = "abc"
x = strtok(NULL, "-="); // x = "def"
x = strtok(NULL, "="); // x = NULL
// s = "abc\0=-def\0"
*/
char *strtok (s, delim)
char *s;
const char *delim;
{
char *token;
if (s == NULL)
s = olds;
/* Scan leading delimiters. */
//strspn : 返回字符串s中第一個不在指定字符串delim中出現的字符下標
//將指針移到第一個非delim中的字符的位置
s += strspn (s, delim);
if (*s == '\0')
{
olds = s;
return NULL;
}
/* Find the end of the token. */
token = s;
// char *strpbrk(const char *token, const char *delim);
// 依次檢驗字符串s中字符,當被檢驗字符在字符串delim中也包含時,則停止檢驗,並返回該字符位置,空字符NULL不包括在內
// 獲取到delim中字符在字符串s中第一次出現的位置
s = strpbrk (token, delim);
if (s == NULL)
/* This token finishes the string. */
olds = __rawmemchr (token, '\0');
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}
//其實現的核心方法在於static char *olds;的方法,用於保存前次處理後的字符串。
舉例說明:
將字符串”Hello,Brief,Kitty”字符串分割為”Hello”、”Brief”、”Kitty”。
代碼可以這樣實現:
#include <stdio.h>
#include <string.h>
int main()
{
int i=0;
char str[] = "Hello,Brief,Kitty";
char *token[3];
char *buf = str;
while((token[i] = strtok(buf, ",")) != NULL)
{
i++;
buf = NULL;
}
for(i=0;i<3;i++)
printf("%s\n",token[i]);
return 0;
}
現在,基於一般的命令行處理,現有以下代碼:
#include <stdio.h>
#include <string.h>
#define MAXLEN 1024
#define MAXCOUNT 64
int main()
{
int i,argc=0;
char *argv[MAXCOUNT],*buf;
char cmdline[MAXLEN];
printf("Please input the command line to be parsed:\n");
if((buf=fgets(cmdline,MAXLEN,stdin))==NULL)
printf("input error!\n");
while((argv[argc] = strtok(buf, " ")) != NULL)
{
argc++;
buf = NULL;
}
printf("There is %d arguments:\n",argc);
for(i=0;i<argc;i++)
printf("%s\n",argv[i]);
return 0;
}
結果為:

最後更新:2017-04-03 05:40:17