Linux C函式strtok解析
1. 今天看了看strtok函式,特意找了下Linux核心2.0.1版本的程式碼,因為在更高版本(至少2.6)已經使用strsep替換了該函式.
函式原型:
char * strtok(char * s,const char * ct)
使用第二個引數ct中的分隔符字串,分割第一個引數s,ct引數的分隔符可以是任意字元,可以是單個字元的分隔符,也可以是字串形式的分隔符如:"!,;'/"等,都可以作為分隔符。例如:
s="abc,def,123;456!/aaa"
ct=",;!/"s將被分割為為:abc def 123 456 aaa
測試程式碼:
[[email protected] algorithm]$ gcc strtok.c -o strtok#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char s[] = "abc,def,123;456!/aaa"; char delim[] = " ,;!/"; char *p = NULL; for(p = strtok(s, delim); p != NULL; p = strtok(NULL, delim)) { printf("%s ", p); } printf("\n"); return 0; }
[[email protected] algorithm]$ ./strtok
abc def 123 456 aaa
2. strtok程式碼分析,以下程式碼摘自Linux2.01.版本:
char * strtok(char * s,const char * ct) { char *sbegin, *send; sbegin = s ? s : ___strtok; if (!sbegin) { return NULL; } sbegin += strspn(sbegin,ct); if (*sbegin == '\0') { ___strtok = NULL; return( NULL ); } send = strpbrk( sbegin, ct); if (send && *send != '\0') *send++ = '\0'; ___strtok = send; return (sbegin); }
先說下strtok的整體思想也就是關鍵的幾個步驟:
a。首先strtok將資料儲存在全域性變數__strtok中,因此不是執行緒安全的也即不可重入。
b。strtok查詢分隔符字串時,跳過連續的分隔符,這樣可以忽略連續分隔符之間的空串,連續分隔符是從源字串開始位置計算,個數通過函式strspn計算得出。
size_t strspn(const char *s, const char *accept),計算字串 str 中連續有幾個字元都屬於字串 accept。
例如:";,/!ABC!/DEF",前四個字元都是分隔符且是連續的,那麼strspn函式返回4,有效資料跳過前4個分隔符就從字元A開始,直到下一分隔符。
c。呼叫函式strpbrk,即源字串中的字元如果與分隔符字串中任意字元相同,就返回指向源字串中該字元的指標,即找到了分隔符,返回該資料的指標。
char * strpbrk(const char * cs,const char * ct),比較字串str1和str2中是否有相同的字元,如果有,則返回該字元在str1中的位置的指標。
例如:";,/!ABC!/DEF",跳過4個分隔符後,從A開始直到遇到分隔符感嘆號(!) 那麼,就返回指向資料起始位置的指標,該指標指向字元A。
細節分析:
a。 變數__strtok是全域性變數,定義在string.c檔案中:char * ___strtok = NULL; 在標頭檔案linux/string.h中進行外部宣告,只要使用該變數的c檔案包含該標頭檔案即可;
b。全域性變數__strtok儲存了剩餘未做分隔的字串的起始地址,每次呼叫strtok函式,都從全域性變數__strtok指向的地址開始查詢引數中的分隔符字串,找到之後__strtok指向本次分隔符的下一位置(有效資料或者結尾符\0,又或者是分隔符如果有連續分隔符的話)。
c。對於字串 "abc,def,123;456!/aaa"; 第一次呼叫strtok之後,分隔符逗號(,)被設定為\0,__strtok設定為指向第一個分隔符逗號之後的資料即__strtok指向字元d,返回指向字元a的指標;第二次呼叫strtok時,從__strtok指向的字元d開始查詢delim中的分隔符,找到第二個逗號時,與第一次操作一樣,分隔符逗號被設定為\0,並從新設定__strtok指向字元1,返回指向字元d的指標,後續一直如此迴圈。
d。如果源字串包含連續分隔符,則呼叫函式strspn計算出連續相同的分隔符字元後會跳過這些分隔符。
附上函式strspn的測試示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int ret = 0;
char s1[] = "abc,;!/}defgh,,,**#123,456";
char s2[] = ";,/#}*abc,;!/}defgh,,,**#123,456";
char delim[] = ",;!/}#*";
ret = strspn(s1, delim);
printf("ret1:%d\n", ret);
ret = strspn(s2, delim);
printf("ret2:%d\n", ret);
return 0;
}
結果如下:
[[email protected] algorithm]$ gcc strspn.c -o strspn
[[email protected] algorithm]$ ./strspn
ret1:0
ret2:6
函式是從源字串開始位置匹配分隔符,只有開始的連續才起作用,開始有1個或者多個則返回匹配到的分隔符個數,如果開始位置一個分隔符都沒有,則返回0,如果有1個則返回1個,上例中返回6個。
相關推薦
Linux C函式strtok解析
1. 今天看了看strtok函式,特意找了下Linux核心2.0.1版本的程式碼,因為在更高版本(至少2.6)已經使用strsep替換了該函式. 函式原型: char * strtok(char * s,const char * ct) 使用第二個引數ct中的分隔符字串,分
linux C函式之stat函式
1.函式功能: 通過檔名filename獲取檔案資訊,並儲存在buf所指的結構體stat中 2.函式原型 1)函式標頭檔案 #include <sys/stat.h> #include <unistd.h> 2)函式 int stat(const c
Linux C 函式速查
...abs abs(計算整型數的絕對值) 相關函式 labs, fabs 表頭檔案 #include<stdli
【轉】Linux C函式庫參考
asctime(將時間和日期以字串格式表示)clock(取得程序佔用CPU的大約時間)ctime(將時間和日期以字串格式表示)difftime(計算時間差距)ftime(取得目前的時間和日期)gettimeofday(取得目前的時間)gmtime(取得目前的時間和日期)loca
linux C函式之access函式的用法【轉】
1.函式功能: 檢查呼叫程序是否可以對指定的檔案執行某種操作。 2.函式原型: 1)函式標頭檔案 #include <stdio.h> #include <unistd.h> 2)函式 int access(
linux c 命令列解析
getopt_long.h標頭檔案,是解析命令列的一個頭檔案,裡面包括了有無及可選引數的定義,以及可選引數的解析 其中看標頭檔案就可以知道getopt_long函式是其主要的功能 其包含巨集定義如下 #define no_argument 0 #def
Linux--C函式
1.函式的定義為了使程式大而不繁,簡單明瞭,程式設計者要根據軟體的總體要求,把相同的功能或相似的操作歸納成模組的形式,並設計成函式,以實現程式設計的結構化。2.函式定義的一般格式型別識別符號 函式名([引數表列]){[宣告部分]語句}呼叫後續宣告的函式時,必須在呼叫之前先進行
Linux C]利用libxml2解析xml檔案
為了解析xml,可以使用Linux下預設安裝的libxml2。/* a.c 功能:利用libxml2解析xml檔案 */#include <stdio.h>#include <stdlib.h>#include <string.h
Linux C 函式指標應用---回撥函式
(這裡引用了知乎上一些知友的回答,感覺不錯,有助於理解,這裡引用作為借鑑,如有冒犯,煩請告知) 我們先來回顧一下函式指標,函式指標是專門用來存放函式地址的指標,函式地址是一個函式的入口地址,函式名代表了函式的入口地址。當一個函式指標指向了一個函式,就可以通過
Linux C獲取時間函式例項
例項詳解Linux下C獲取時間函式的程式碼。 一、time 標頭檔案: #include <time.h> 原型: time_t time(time_t *t) time_t的定義: typedef __darwin_time_t time_t; typedef long
【C語言】字串函式strtok 按照指定字串分割
C語言字串函式 strtok() 函式原型 char *strtok(char *str,const char *delimiters); 引數 str,待分割的字串 delimiters,分隔符字串 該函式用來將字串str分割成一個個片段。 引數str指
Linux C 中獲取local日期和時間 time()&localtime()函式
1. time() 函式 /* time - 獲取計算機系統當前的日曆時間(Calender Time) * 處理日期時間的函式都是以本函式的返回值為基礎進行運算 * 函式原型: * #include <time.h>
軟體素材---linux C語言:linux下獲取可執行檔案的絕對路徑--getcwd函式
//標頭檔案:#include <unistd.h> //定義函式:char * getcwd(char * buf, size_t size);  
軟體素材---linux C語言:拼接字串函式 strcat的用例(與char陣列聯合使用挺好)
【標頭檔案】#include <string.h> 【原型】 1 char *strcat(char *dest, const char *src); 【引數】: dest 為目標字串指標,src 為源字串指標。
C++ 函式呼叫過程中棧的變化解析
“ 走好選擇的路,別選擇好走的路,你才能擁有真正的自己。” There you go again! I'll back you up! 記錄下函式呼叫的情況~ 函式呼叫的另一個詞語表示叫作 過程。一個過程呼叫包括將資料和控制從程式碼的一部分傳遞到另一部分。
C++ 虛擬函式表解析
1 前言 C++中的虛擬函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以讓父類的指標有“多種形態”,這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的程式碼來實現
Linux常用C函式
可以參考這個: /第三章 檔案IO******************************************/ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 函
Linux C高階程式設計——網路程式設計之包裹函式
Linux網路程式設計(六)——包裹函式 宗旨:技術的學習是有限的,分享的精神是無限的。 系統呼叫不能保證每次都成功,必須進行出
Linux C高階程式設計——檔案操作之庫函式
Linux C高階程式設計——檔案操作之庫函式 宗旨:技術的學習是有限的,分享的精神是無限的 ——為什麼要設計標準I/O庫? 直接使用API進行檔案訪問時,需要考慮許多細節問題 例如:read、write時,緩衝區的大小該如何確定,才能使效率最優 標準I/O庫封裝了諸多