小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

字符串分割函數(shù)strtok

 書劍閣2013 2014-08-04

前天晚上和 xiaofazhen 看程序, 突然間看到他的代碼里有 strtok 這么一個函數(shù), 網(wǎng)上查了一下, 居然是用來做字符串分割的;

原來 C 下還是有這函數(shù)的, 以前還一直抱怨 C 下沒有字符串分割函數(shù), 很不方便, 看來還是自己孤陋寡聞胃(如果是 C++ 的話, 參照 這里, 使用 copy+istringstream 來實(shí)現(xiàn)); 不多說, 既然看到了, 就要好好學(xué)習(xí)一下.

以下代碼測試環(huán)境為:  Windows7 + Visual Studio 2010

函數(shù)原型:

1
2
3
4
char *strtok(
   char *strToken,
   const char *strDelimit
);


參數(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ò)改.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// crt_strtok.c
// compile with: /W3
// In this program, a loop uses strtok
// to print all the tokens (separated by commas
// or blanks) in the string named "string".
//
#include <string.h>
#include <stdio.h>
#include <Windows.h>
char string[] = "A string\tof ,,tokens\nand some  more tokens";
char seps[]   = " ,\t\n";
char chinese[] = "中國,吃飯";
char *token;
int main( void )
{
    printf( "英文測試:\n" );
    // Establish string and get the first token:
    token = strtok( string, seps ); // C4996
    // Note: strtok is deprecated; consider using strtok_s instead
    while( token != NULL )
    {
        // While there are tokens in "string"
        printf( " %s\n", token );
        // Get next token:
        token = strtok( NULL, seps ); // C4996
    }
    printf("原字符串: %s\n", string);   // 結(jié)果為 A, 說明原字符串已發(fā)生改變
    printf( "\n中文測試:\n");
    token = strtok( chinese, ",");
    while(token != NULL )
    {
        printf( "%s\n", token);
        token = strtok( NULL, ",");
    }
    printf("\n");
    system("pause");
}


運(yùn)行結(jié)果:

可以看到, 即使是全中文組成的字符串, 也是能正確分割的; 還要注意的一點(diǎn)是, 調(diào)用 strtok 后, 原字符串會被修改.

clip_image002

 

 

最后, 百度百科說明在新的 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

 

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多