# C 語言的 strtok

C 語言要字串分割通常會使用 strtok,要使用 strtok 的話需要引入的標頭檔 <string.h> ,如果要使用 C++ 的標頭檔則是引入 <cstring>

strtok 函式原型為

strtok
char* strtok(char* str, const char* delimiters);

strtok() 會將 str 依據給入的 delimiters (分割符號 / 分隔符號) 進行字串分割,如果成功的話會回傳指向分割結果的字串開頭否則會回傳 NULL

# Example

d 是分割符號 / 分隔符號,這邊示範用空格逗號進行分割,如果有需要的話還可以在 delimiters 加入更多的分割符號,
p指向每次分割的結果

要注意的是除了第一次是將 str 帶入 strtok 分割以外,第二次以上都是將 NULL 帶入 strtok 繼續作字串分割

strtok()Home
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
ing main() {
    char str[] = "Hello world, nice to meet you";
    const char* d = " ,";
    char* p;
    p = strtok(str, d);
    while (p != NULL) {
        printf("%s\n", p);
        p = strtok(NULL, d);
    }
}

結果如下,

Hello
world
nice
to
meet
you

因為 strtok 的實做原理是發現分割字元時,就把字元改為 \0 字元,意味著使用 strtok() 完後,原字串會被修改
修改後的結果是 Hello\nworld\n\nnice\nto\nmeet\nyou 這樣的形式,所以原本的字串如果之後另有用途的話,記得先複製一份。

# C++ find() & substr()

std::string::find() 可以用來作字串搜尋的功能,再將每次找到的位置搭配 std::string::substr() 取出子字串並放入 std::vector 裡,最後再回傳這個結果 std::vector<std::string> result ,這種方式的好處是原字串不會被修改。

find() & substr()Home
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const vector<string> split(const string& str, const string& pattern) {
    vector<string> res;
    string::size_type begin, end;
    end = str.find(pattern);
    begin = 0;
    while (end != string::npos) {
        if (end - begin != 0) {
            res.push_back(str.substr(begin, end - begin));
        }
        begin = end + pattern.size();
        end = str.find(pattern, begin);
    }
    if (begin != str.length()) {
        res.push_back(str.substr(begin));
    }
    return res;
}
int main() {
    string str = "This is a C++ string";
    string pattern = " ";
    vector<string> v = split(str, pattern);
    for (auto& s : v) cout << s << endl;
}

結果如下,

This
is
a
C++
string

# C++ getline()

先將 string 建立 stringstream ,再用 getline() 來處理 stringstream ,將每一次取出的字串放到 vector ,最後再回傳這個結果 vector<string> result ,這種方式的好處是原字串不會被修改。

getline()Home
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
const vector<string> split(const string& str, const char& delimiter) {
    vector<string> res;
    stringstream ss(str);
    string tok;
    while (getline(ss, tok, delimiter)) {
        res.push_back(tok);
    }
    return res;
}
int main() {
    string str = "This is a C++ string";
    vector<string> v = split(str, ' ');
    for (auto& s: v) cout << s << endl;
}

結果如下,

This
is
a
C++
string

# 參考資料

  • https://shengyu7697.github.io/cpp-string-split/