一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

strtok()函數(shù)

 wsglibrary 2016-04-14

strtok()這個(gè)函數(shù)大家都應(yīng)該碰到過(guò),但好像總有些問(wèn)題, 這里著重講下它

首先看下MSDN上的解釋:

char *strtok( char *strToken, const char *strDelimit );

Parameters

strToken

String containing token or tokens.

strDelimit

Set of delimiter characters.

Return Value

Returns a pointer to the next token found in strToken. They return NULL when no more tokens are found. Each call modifies strToken by substituting a NULL character for each delimiter that is encountered.

Remarks

The strtok function finds the next token in strToken. The set of characters in strDelimitspecifies possible delimiters of the token to be found in strToken on the current call.

Security Note    These functions incur a potential threat brought about by a buffer overrun problem. Buffer overrun problems are a frequent method of system attack, resulting in an unwarranted elevation of privilege. For more information, see Avoiding Buffer Overruns.

On the first call to strtok, the function skips leading delimiters and returns a pointer to the first token in strToken, terminating the token with a null character. More tokens can be broken out of the remainder of strToken by a series of calls to strtok. Each call tostrtok modifies strToken by inserting a null character after the token returned by that call. To read the next token from strToken, call strtok with a NULL value for the strTokenargument. The NULL strToken argument causes strtok to search for the next token in the modified strToken. The strDelimit argument can take any value from one call to the next so that the set of delimiters may vary.

Note   Each function uses a static variable for parsing the string into tokens. If multiple or simultaneous calls are made to the same function, a high potential for data corruption and inaccurate results exists. Therefore, do not attempt to call the same function simultaneously for different strings and be aware of calling one of these functions from within a loop where another routine may be called that uses the same function. However, calling this function simultaneously from multiple threads does not have undesirable effects.

很暈吧? 呵呵。。。

簡(jiǎn)單的說(shuō),就是函數(shù)返回第一個(gè)分隔符分隔的子串后,將第一參數(shù)設(shè)置為NULL,函數(shù)將返回剩下的子串。

下面我們來(lái)看一個(gè)例子:

int main() 

{

      char test1[] = "feng,ke,wei";  

      char *test2 = "feng,ke,wei";  

      char *p;  

      p = strtok(test1, ",");

      while(p)  

          {   

              printf("%s\n", p);   

              p = strtok(NULL, ",");     

          }      

      return 0;

 }

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

feng

ke

wei

 

說(shuō)明:

函數(shù)strtok將字符串分解為一系列標(biāo)記(token),標(biāo)記就是一系列用分隔符(delimiting chracter,通常是空格或標(biāo)點(diǎn)符號(hào))分開(kāi)的字符。注意,此的標(biāo)記是由delim分割符分割的字符串喔。

例如,在一行文本中,每個(gè)單詞可以作為標(biāo)記,空格是分隔符。
需要多次調(diào)用strtok才能將字符串分解為標(biāo)記(假設(shè)字符串中包含多個(gè)標(biāo)記)。第一次調(diào)用strtok包含兩個(gè)參數(shù),即要標(biāo)記化的字符串和包含用來(lái)分隔標(biāo)記的字符的字符串(即分隔符)下列語(yǔ)句: tokenPtr = Strtok(string, " ")
tokenPtr賦給string中第一個(gè)標(biāo)記的指針。strtok的第二個(gè)參數(shù)””表示string中的標(biāo)記用空格分開(kāi)。
函數(shù)strtok搜索string中不是分隔符(空格)的第一個(gè)字符,這是第一個(gè)標(biāo)記的開(kāi)頭。然后函數(shù)尋找字符串中的下一個(gè)分隔符,將其換成null(, w,)字符,這是當(dāng)前標(biāo)記的終點(diǎn)。注意標(biāo)記的開(kāi)始于結(jié)束。

函數(shù)strtok保存string中標(biāo)記后面的下一個(gè)字符的指針,并返回當(dāng)前標(biāo)記的指針。


后面再調(diào)用strtok時(shí),第一個(gè)參數(shù)為NULL,繼續(xù)將string標(biāo)記化。NULL參數(shù)表示調(diào)用strtok繼續(xù)從string中上次調(diào)用 strtok時(shí)保存的位置開(kāi)始標(biāo)記化。

如果調(diào)用strtok時(shí)已經(jīng)沒(méi)有標(biāo)記,則strtok返回NULL。注意strtok修改輸入字符串,因此,如果調(diào)用strtok之后還要在程序中使用這個(gè)字符串,則應(yīng)復(fù)制這個(gè)字 符串。

但如果用p = strtok(test2, ",")則會(huì)出現(xiàn)內(nèi)存錯(cuò)誤,這是為什么呢?是不是跟它里面那個(gè)靜態(tài)變量有關(guān)呢? 我們來(lái)看看它的原碼:

/***

*strtok.c - tokenize a string with given delimiters

*

*       Copyright (c) Microsoft Corporation. All rights reserved.

*

*Purpose:

*       defines strtok() - breaks string into series of token

*       via repeated calls.

*

*******************************************************************************/

#include

#include

#ifdef _MT

#include

#endif  /* _MT */

/***

*char *strtok(string, control) - tokenize string with delimiter in control

*

*Purpose:

*       strtok considers the string to consist of a sequence of zero or more

*       text tokens separated by spans of one or more control chars. the first

*       call, with string specified, returns a pointer to the first char of the

*       first token, and will write a null char into string immediately

*       following the returned token. subsequent calls with zero for the first

*       argument (string) will work thru the string until no tokens remain. the

*       control string may be different from call to call. when no tokens remain

*       in string a NULL pointer is returned. remember the control chars with a

*       bit map, one bit per ascii char. the null char is always a control char.

*       //這里已經(jīng)說(shuō)得很詳細(xì)了!!MSDN都好!

*Entry:

*       char *string - string to tokenize, or NULL to get next token

*       char *control - string of characters to use as delimiters

*

*Exit:

*       returns pointer to first token in string, or if string

*       was NULL, to next token

*       returns NULL when no more tokens remain.

*

*Uses:

*

*Exceptions:

*

*******************************************************************************/

char * __cdecl strtok (

        char * string,

        const char * control

        )

{

        unsigned char *str;

        const unsigned char *ctrl = control;

        unsigned char map[32];

        int count;

#ifdef _MT

        _ptiddata ptd = _getptd();

#else  /* _MT */

        static char *nextoken;                        //保存剩余子串的靜態(tài)變量   

#endif  /* _MT */

        /* Clear control map */

        for (count = 0; count < 32; count++)

                map[count] = 0;

        /* Set bits in delimiter table */

        do {

                map[*ctrl >> 3] |= (1 << (*ctrl & 7));

        } while (*ctrl++);

        /* Initialize str. If string is NULL, set str to the saved

         * pointer (i.e., continue breaking tokens out of the string

         * from the last strtok call) */

        if (string)

                str = string;                             //第一次調(diào)用函數(shù)所用到的原串       

else

#ifdef _MT

                str = ptd->_token;

#else  /* _MT */

                str = nextoken;                      //將函數(shù)第一參數(shù)設(shè)置為NULL時(shí)調(diào)用的余串

#endif  /* _MT */

  /* Find beginning of token (skip over leading delimiters). Note that
         * there is no token iff this loop sets str to point to the terminal
         * null (*str == '\0') */
        while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
                str++;
        string = str;                                  //此時(shí)的string返回余串的執(zhí)行結(jié)果 
        /* Find the end of the token. If it is not the end of the string,
         * put a null there. */
//這里就是處理的核心了, 找到分隔符,并將其設(shè)置為'\0',當(dāng)然'\0'也將保存在返回的串中
        for ( ; *str ; str++ )
                if ( map[*str >> 3] & (1 << (*str & 7)) ) {
                        *str++ = '\0';              //這里就相當(dāng)于修改了串的內(nèi)容 
                        break;
                }
        /* Update nextoken (or the corresponding field in the per-thread data
         * structure */
#ifdef _MT
        ptd->_token = str;
#else  /* _MT */
        nextoken = str;                 //將余串保存在靜態(tài)變量中,以便下次調(diào)用
#endif  /* _MT */
        /* Determine if a token has been found. */
        if ( string == str )
              return NULL;
        else
                return string;
}

原來(lái), 該函數(shù)修改了原串

所以,當(dāng)使用char *test2 = "feng,ke,wei"作為第一個(gè)參數(shù)傳入時(shí),在位置, 由于test2指向的內(nèi)容保存在文字常量區(qū),該區(qū)的內(nèi)容是不能修改的,所以會(huì)出現(xiàn)內(nèi)存錯(cuò)誤. char test1[] = "feng,ke,wei" 中的test1指向的內(nèi)容是保存在棧區(qū)的,所以可以修改.

看到這里  大家應(yīng)該會(huì)對(duì)文字常量區(qū)有個(gè)更加理性的認(rèn)識(shí)吧.....

 

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    九九九热视频最新在线| 精品亚洲香蕉久久综合网| 国内精品偷拍视频久久| 国产成人人人97超碰熟女| 91免费精品国自产拍偷拍| 中文字幕人妻av不卡| 日韩av欧美中文字幕| 欧美日韩一区二区综合| 日韩18一区二区三区| 国产精品欧美在线观看| 国产午夜精品亚洲精品国产| 国产精品日韩精品最新| 大屁股肥臀熟女一区二区视频| 亚洲精品福利视频在线观看| 午夜视频成人在线观看| 亚洲精品国男人在线视频| 国产中文字幕久久黄色片| 久久热麻豆国产精品视频| 欧美尤物在线观看西比尔| 亚洲国产精品一区二区毛片| 国产又粗又长又大高潮视频| 女生更色还是男生更色| 隔壁的日本人妻中文字幕版 | 少妇人妻中出中文字幕| 国产精品国三级国产专不卡| 久久精品久久精品中文字幕| 中文字幕91在线观看| 伊人久久青草地综合婷婷| 国产一级不卡视频在线观看| 欧美日韩国产综合在线| 日韩av亚洲一区二区三区| 免费观看日韩一级黄色大片| 国产主播精品福利午夜二区| 亚洲夫妻性生活免费视频| 成年男女午夜久久久精品| 国产成人精品久久二区二区| 久久碰国产一区二区三区| 99久久国产综合精品二区| 日本熟女中文字幕一区| 亚洲专区一区中文字幕| 亚洲专区一区中文字幕|