C++中的字符串分割函數-----strtok

strtok函數原型:strtok(OriginalString,Seps)

參數:

OriginalString代表等待分割的字符串(char*類型)

Seps代表的也是一個字符串(const char*類型),裏面防止什麼符號是分隔符。eg: Seps=" ,!.n" 表示空格,逗號,感嘆號,n都是分割當前字符串的分隔符

運行後產生兩個指針:(詳情見下面程序註釋)

第一個指針pointer_a用來指向函數返回的字符串,這個字符串是被原字符串OriginalString被seps中的字符截斷後的第一個字符串。

第二個指針pointer_b用來指向OriginalString中,匹配截斷字串seps的位置。

注意:

strtok會破壞被分割的字符串。eg: 被分割的是str數組,那麼分割完成後,str指向的只是第一個被分割的所有子串中的第一個子串

strtok函數實例:

//這個代碼寫的繁瑣了一點,主要是爲了理解strtok的運行原理,後面第二份代碼進行了簡化
#include <stdio.h>
#include <string.h> //必須包含此頭文件 
int main()
{
    char *p;
    char str[100]="You are so beautiful a girl.I love you!";

    p = strtok(str," ,.!"); // 此時得到的 p指向字符串:"You",第一個符合標準的分隔符會被替換爲
			    //空指針(NULL),所以此時NULL指針指向後面
			    //的字符串:"are so beautiful a girl.I love you!"
    printf("len:%d str:%s\n",strlen(p),p);
    do{
        p = strtok(NULL, " ,.!");  // NULL 即爲上面返回的指針,指向
				   //字符串:"are so beautiful a girl.I love you!"。
        if(p){
        	printf("len:%d str:%s\n",strlen(p),p);
                //我爲什麼要寫strlen(p)呢?是爲了表明,我們可以把
	        //這個p當做一個字符串數組來對待 
	}    
    }while(p);

    return 0;
} 

程序運行結果:

strtok函數中的NULL問題:

上述已經講解,函數運行後會得到兩個參數。以上述程序第一次運行strtok爲例:

函數的返回值pointer_a爲一個指向”You”的指針。此時,對於pointer_b,我更傾向於它指向了剩下的字符串,即"are so beautiful a girl.I love you!"
只要把strtok()的第一個參數設置爲NULL,就可以直接對pointer_b指向的字符串開始進行新一輪的查找匹配了


因此使用方法是:首次調用時,s必須指向要分解的字符串,隨後調用要把s設成NULL。
strtok在s中查找包含在Seps中的字符並用NULL(’\0’)來替換,直到找遍整個字符串。(這樣是不是有種感覺,字符串在內存中的位置並沒有改變,只是把那些分隔符置爲字符串的結束標誌'\0',並且得到了每一個子串的起始位置的指針)

關於如何保存分割後字符串的問題:

上面的程序確實是對其做了分割,但第一時間就打印了。而我們更多的時候是希望可以將其保存下來,應該怎麼做。

首先,我們不知道分割後會產生多少個子串,所以我們需要一個動態容器來添加。(python大法好,split和list是真方便,忍不住吐槽)但C++有vector。

所以我設置了一個 vector<char*> s; 來動態添加保存每一個子串

#include <stdio.h>
#include <string.h> //必須包含此頭文件 
#include <vector>
using namespace std;
void split(vector<char*> *s,char *str,const char *c); 
using namespace std; 
int main()
{
    vector<char*> s;
    char str[100]="You are so beautiful a girl.I love you!";
    
    split(&s,str," ,.!");
    
    printf("分割後子串的個數:%d\n",s.size());
    for(int i=0; i<s.size(); i++){
    	printf("%s\n",s[i]);
    }
    return 0;
} 
void split(vector<char*> *s,char *str,const char *c)
{
    char *p;
    p = strtok(str, c);
    while(p){
	(*s).push_back(p);
        p = strtok(NULL, c); 
    }  
}

程序運行結果:

綜上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章