常用的字符串分割方法


起因:前段時間寫命令行解析函數(字符串分割比較通用的例子),沒有經過深入思考和分析引起了程序死循環,就想了下是否有對應的系統函數可以使用。經過一番搜索之后發現還是有幾個可用的字符串分割函數,這里整理下,以作總結及后續查詢使用。

當然,如果你覺得自己的字符串處理可以做的很好,可以考慮直接使用字符串查找函數做字符串分割,比如c中的字符串查找函數、CString字符查找函數、string字符查找函數等,更原始點可以直接操作內存。

 

windows下有以下幾種可用的字符串分割方法。 

CString::Tokenize()

用法如下。

// 按照token分割source字符串,結果通過cout輸出
// 使用MFC的CString::Tokenize
void SplitUseTokenize(const char * source, char token)
{

	CString strSource = source;
	CString strToken(token);

	int pos = 0;
		
	while (-1 != pos)
	{
		CString strCur = strSource.Tokenize(strToken, pos);

		if (!strCur.IsEmpty())
		{
			cout << strCur << endl;
		}
	}

	cout << endl << endl;
}

Tokenize函數將分割好的字串放到返回值中,同時將對應的掃描位置放到第二個參數中,如果第二個參數返回-1,表示分割完成。

AfxExtractSubString()函數

// 按照token分割source字符串,結果通過cout輸出
// 使用MFC中的AfxExtractSubString函數
void SplitUseExtract(const char * source, char token)
{
	int pos = 0;
	CString strCur = "";
	while(AfxExtractSubString(strCur, source, pos, token))
	{
		++pos;
		cout << strCur << endl;
	}

	cout << endl << endl;
}

 AfxExtractSubString函數返回值表示是否提取子串成功,還有幾個重載函數,可以參考msdn上的說明。

提取得到子串放到第一個參數中。 

c語言的strtok()函數

// 按照token分割source字符串,結果通過cout輸出
// 使用crt的strtok函數
void SplitUseStrtok(char * source, char token)
{
	char * ptr = strtok(source, &token);
	while(NULL != ptr)
	{   
		cout << ptr << endl;
		ptr = strtok(NULL, &token);
	}
}

strtok函數不是線程安全的,不是可重入的,需要線程安全的函數,建議使用strtok_r函數。具體用法可參考c語言用戶手冊。 

 

這里需要說明的是:

CString::Tokenize()中的PCXSTR pszTokens為分隔字符的組合,可為多個字符。

AfxExtractSubString()中的分隔字符,只能是一個字符。

另外有一點要注意:

CString::Tokenize()碰到連續多個分隔字符是作為一個處理的,AfxExtractSubString()中多個分隔符可區分處理。

strtok/strtok_r函數的處理邏輯跟CString::Tokenize()類似。

如果使用下面測試程序,輸出如下:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// 初始化 MFC 並在失敗時顯示錯誤
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: 更改錯誤代碼以符合您的需要
		_tprintf(_T("錯誤: MFC 初始化失敗\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: 在此處為應用程序的行為編寫代碼。
		char source[] = "123\n\n456\n789";
		char token = '\n';
		SplitUseTokenize(source, token);
		SplitUseExtract(source, token);
		SplitUseStrtok(source, token);

		system("pause");
	}

	return nRetCode;
}

  

這個輸出也說明了本文中提及的注意事項問題。

 

注:本文涉及所有代碼可使用Git直接下載:https://git.oschina.net/Tocy/SampleCode.git。實際代碼位於Console目錄下,名稱為“20150709_StringSplit.cpp”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM