|
前天晚上和 xiaofazhen 看程序, 突然間看到他的代碼里有 strtok 這么一個函數(shù), 網(wǎng)上查了一下, 居然是用來做字符串分割的; 原來 C 下還是有這函數(shù)的, 以前還一直抱怨 C 下沒有字符串分割函數(shù), 很不方便, 看來還是自己孤陋寡聞胃(如果是 C++ 的話, 參照 這里, 使用 copy+istringstream 來實(shí)現(xiàn)); 不多說, 既然看到了, 就要好好學(xué)習(xí)一下. 以下代碼測試環(huán)境為: Windows7 + Visual Studio 2010 函數(shù)原型:
參數(shù)說明: strToken: 包含 token 的字符串, 即待分割串strDelimit: token 的集合, strToken 會根據(jù)這里的每個字符進(jìn)行分割
返回值: 返回指向第一段被截取出來的字符串的指針(根據(jù) strDelimit 內(nèi)的字符進(jìn)行截取). 如果沒有找到, 那么就返回 NULL.
調(diào)用說明: (1). 第一次調(diào)用 strtok 時, 第一個參數(shù)是 strToken, 以后再調(diào)用時, 第一個參數(shù)必須是 NULL;(2). 調(diào)用 strtok 后, 原字符串會被修改; (3). strtok 不是一個線程安全的函數(shù).
源代碼分析: 從 這里 貼出的 Linux 下的 string.h 的實(shí)現(xiàn)可以看出:(1). strtok 使用一個全局定義的 char * ___strtok; 來指向截取后的剩余字符串, 所以從第二次開始調(diào)用 strtok 后, 第一個參數(shù)就只需要設(shè)為 NULL 就可以了; (2). strtok 函數(shù)會在一開始就判斷其第一個參數(shù), 若不為 NULL, 就取其第一個參數(shù)進(jìn)行截取, 并將 ___strtok 指向截取后的字符串; 若為NULL, 則使用 ___strtok 進(jìn)行截取, 并將 ___strtok 指向截取后的字符串; (3). strtok 使用 sbegin 指向待截取的字符串, 當(dāng)找到 strDelimit 里的字符時, 就在這個字符前面插入 '\0', 這樣就相當(dāng)于從 sbegin 指向的字符串里截取出前面一段了. 而后面一段, 則由 ___strtok 指向, 等待下一次截取.
測試代碼: 原始代碼摘自 msdn, 有擴(kuò)改.
運(yùn)行結(jié)果: 可以看到, 即使是全中文組成的字符串, 也是能正確分割的; 還要注意的一點(diǎn)是, 調(diào)用 strtok 后, 原字符串會被修改.
最后, 百度百科說明在新的 Linux 2.6.29 下, 不再使用 strtok 函數(shù), 而是改為使用更快的 strsep 替代. 但是在 windows 環(huán)境下(當(dāng)前版本 Visual Studio 2010), 并未提供 strsep 函數(shù). 在 這里 可以看到 strsep 的函數(shù)實(shí)現(xiàn), 所以可以自己寫一個 strsep, 然后再調(diào)用即可. 在 strtok 函數(shù)定義處也可以看到以下說明"WARNING: strtok is deprecated, use strsep instead.".
============================================================== 這篇文章《C語言中strtok函數(shù)進(jìn)行分割字符串!》寫的也不錯, 可以參考。
環(huán)境: Windows7 + Visual Studio 2010
|
|
|