拆分字符串爲vector
字符串分割,在網上看到幾種方法https://www.jb51.net/article/55954.htm
1 使用strtok分割
//藉助strtok實現split
#include <string.h>
#include <stdio.h>
int main()
{
char s[] = "Golden Global View,disk * desk";
const char* d = " ,*";
char* p;
p = strtok(s, d);
while (p)
{
printf("%s\n", p);
p = strtok(NULL, d);
}
return 0;
}
但是 strtok 在高版本的vs 中需要定義 _CRT_NON_CONFORMING_WCSTOK才能使用,而且在內部實現有
_SECURE_VERSION版本和非安全版本,非安全版本多線程同時訪問會可能會發生問題。
2 用STL進行字符串的分割
//字符串分割函數
std::vector<std::string> split(std::string str, std::string pattern)
{
std::string::size_type pos;
std::vector<std::string> result;
str += pattern;//擴展字符串以方便操作
int size = str.size();
for (int i = 0; i < size; i++)
{
pos = str.find(pattern, i);
if (pos < size)
{
std::string s = str.substr(i, pos - i);
result.push_back(s);
i = pos + pattern.size() - 1;
}
}
return result;
}
這個例子沒有考慮多個拆分符的情況
3 使用boost 庫
這種情況不貼代碼了,就是庫的使用,boost太大,不喜歡
這裏再介紹一種方法
根據基本的有窮自動機
- 我們實現對分隔符的處理
- 0 是初始狀態
- 1 的時候接收到一個普通字符
- 2 是結束狀態
- 處理分隔符在 狀態1->0跳轉的時候處理,保存字符串
- 從0-2 從 1->2 是退出
- 下面貼代碼
template<class T>
bool in_string(T c, const T* str)
{
while (*str)
{
if (*str++ == c)
{
return true;
}
}
return false;
}
void split_string(
string& roldids,
string& split_str,
vector<string>& vec)
{
int i = 0;
int pos = -1;
char c = 0;
int stat = 0;
while (true)
{
char c = roldids[i];
switch (stat)
{
case 0:
{
if (!in_string(c, split_str.data()))
{
stat = 1;
pos = i;
}
if (c == 0)
{
return;
}
break;
}
case 1:
if (in_string(c, split_str.data()) || (c == 0 && pos != roldids.size() - 1))
{
string s;
s.insert(s.begin(), roldids.begin() + pos, roldids.begin() + i);
vec.push_back(s);
stat = 0;
}
if (c == 0)
{
return;
}
break;
}
i++;
}
}
- 上面代碼就是拆分函數,輸出到vector中去
- 下面是測試函數
int main()
{
//測試用例
//1 使用一種分割符 3 個測試用例
//2 使用混合分隔符
//3 分割符在最前
//4 分割符在最後
//5 分隔符湊在一起
string s = "hello,welcome,to beijing,歡迎到中國來;啦啦啦";
string split_str = ", ;";
vector<string> vec;
split_string(s, split_str, vec);
s = ",; hello,welcome,to,beijing, ; ";
vec.clear();
split_string(s, split_str, vec);
return 0;
}
- 僅僅使用了有窮自動機畫了個簡單的圖就搞定了。如果使用正則表達式的庫或許威力更大,但是少了些樂趣。
- 下面完整代碼
// 各種類型轉字符串.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <cstdint>
#include <iostream>
#include <string>
#include <list>
#include <string.h>
#include <iomanip> // std::setw
#include <vector>
using namespace std;
std::string to_utf8(int32_t v)
{
char b[8] = {};
_itoa_s(v, b, 10);
return b;
}
template<class T>
bool in_string(T c, const T* str)
{
while (*str)
{
if (*str++ == c)
{
return true;
}
}
return false;
}
void split_string(
string& roldids,
string& split_str,
vector<string>& vec)
{
int i = 0;
int pos = -1;
char c = 0;
int stat = 0;
while (true)
{
char c = roldids[i];
switch (stat)
{
case 0:
{
if (!in_string(c, split_str.data()))
{
stat = 1;
pos = i;
}
if (c == 0)
{
return;
}
break;
}
case 1:
if (in_string(c, split_str.data()) || (c == 0 && pos != roldids.size() - 1))
{
string s;
s.insert(s.begin(), roldids.begin() + pos, roldids.begin() + i);
vec.push_back(s);
stat = 0;
}
if (c == 0)
{
return;
}
break;
}
i++;
}
}
int main()
{
//測試用例
//1 使用一種分割符 3 個測試用例
//2 使用混合分隔符
//3 分割符在最前
//4 分割符在最後
//5 分隔符湊在一起
string s = "hello,welcome,to beijing,歡迎到中國來;啦啦啦";
string split_str = ", ;";
vector<string> vec;
split_string(s, split_str, vec);
s = ",; hello,welcome,to,beijing, ; ";
vec.clear();
split_string(s, split_str, vec);
return 0;
}