C++之split字符串分割


在C++中沒有直接對應的split函數,字符串分割可借助以下方法實現:

1、借助strtok函數

函數原型:char * strtok (char *str, char * delim);

函數功能:以delim為分隔符分割字符串str

參數說明:str:要分隔的字符串;delim:分隔符

返回值:從str開頭開始的一個個被分割的字符串。當沒有被分割時則返回null

代碼1:直接使用strtok函數分割char*類型的字符串

 代碼2:借助strtok分割string類型的字符串,將結果保存在vector<string>中

 

#include <iostream>
using namespace std;
 
int main() {
	char s[] = "my name is lmm";
	char *p;
	const char *delim = " ";
	p = strtok(s, delim);
	while(p) {
		cout << p << endl;
		p = strtok(NULL, delim);
	}
 
	return 0;
}

  

思路:先將整個string字符串轉換為char*類型,分割后得到char*類型的子字符串,將子字符串轉換為string類型,並存入結果數組中。

#include <iostream>
#include <vector>
using namespace std;
 
vector<string> split(const string& str, const string& delim) {
	vector<string> res;
	if("" == str) return res;
	//先將要切割的字符串從string類型轉換為char*類型
	char * strs = new char[str.length() + 1] ; //不要忘了
	strcpy(strs, str.c_str()); 
 
	char * d = new char[delim.length() + 1];
	strcpy(d, delim.c_str());
 
	char *p = strtok(strs, d);
	while(p) {
		string s = p; //分割得到的字符串轉換為string類型
		res.push_back(s); //存入結果數組
		p = strtok(NULL, d);
	}
 
	return res;
}
 
void test1() { //空字符串
	cout << "******test1****** "<<endl;
	string s = "";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
void test2() { //只有一個字符串
	cout << "******test2****** " <<endl;
	string s = "my";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
void test3() { //正常字符串
	cout << "******test3****** "<<endl;
	string s = "my name is lmm   ";//連續多個空格,空格會被過濾掉
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
 
int main() {
 
	test1();
	test2();
	test3();
	return 0;
}

  

注意:test3中連續多個空格出現,空格都會被過濾掉

2、借助於string類的find和substr函數

1)find函數

函數原型:size_t find(const string& str, size_t pos = 0) const;

功能說明:從pos位置開始查找子字符串str第一次出現的位置

參數說明:str為要查找的子字符串,pos從為初始查找位置

返回值:找到的話返回子字符串第一次出現的位置,否則返回string::npos

2)substr函數

函數原型:string substr(size_t pos = 0, size_t n = npos) const;

功能說明:獲取從指定的起始位置開始,長度為n的子字符串

參數說明:pos為起始位置,n獲取的1字符串長度

返回值:子字符串

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
 
string reverse_one_word(string str) {
	for(int i = 0; i < str.length()/2; i ++) {
		char tmp;
		tmp = str[i];
		str[i] = str[ str.length() - i - 1 ];
		str[ str.length() - i - 1 ] = tmp;
	}
	return str;
}
 
vector<string>  split(const string& str,const string& delim) { //將分割后的子字符串存儲在vector中
	vector<string> res;
	if("" == str) return  res;
	
	string strs = str + delim; //*****擴展字符串以方便檢索最后一個分隔出的字符串
	size_t pos;
	size_t size = strs.size();
 
	for (int i = 0; i < size; ++i) {
		pos = strs.find(delim, i); //pos為分隔符第一次出現的位置,從i到pos之前的字符串是分隔出來的字符串
		if( pos < size) { //如果查找到,如果沒有查找到分隔符,pos為string::npos
			string s = strs.substr(i, pos - i);//*****從i開始長度為pos-i的子字符串
			res.push_back(s);//兩個連續空格之間切割出的字符串為空字符串,這里沒有判斷s是否為空,所以最后的結果中有空字符的輸出,
			i = pos + delim.size() - 1;
		}
		
	}
	return res;	
}
 
void test1() { //空字符串
	cout << "******test1****** "<<endl;
	string s = "";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
void test2() { //只有一個字符串
	cout << "******test2****** " <<endl;
	string s = "my";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
void test3() { //正常字符串
	cout << "******test3****** "<<endl;
	string s = "my name is  lmm   ";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}
 
 
int main() {
 
	test1();
	test2();
	test3();
	return 0;
}

  

注意:test3中的多個空格未被過濾掉,也就是說兩個空格分隔符之間的空子串也被存進了結果數組中。要想避免這個問題可以在分隔出子字符串s時,判斷一下若為空(兩個分隔符相鄰,中間的子串為空),則不加入字符數組即可去掉。


免責聲明!

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



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