如何在C++中使用类似python的字符串split()函数

在处理文本的过程中,最常用的做法就是将它分离成一栏一栏的,比如系统日志, 从中提取出自己需要的部分用于不同的用途,并将剩下的部分抛弃。令人惊讶的是,C++中的string类缺乏一种分离自身的方法(或函数)。取而代之的是strtok()函数,然而事实上这并不是真正属于"C++"的方法,它使用的是"C"当中的字符数组而不是"C++"的string类,而且它需要一个传递一个指针来帮助它运行。

在这个样例中我从string类中分化出了一个splitstring类。对于一个splitstring而言,你可以将它当做普通的string类字符串使用,因为它本质上还是一个字符串,但是与string类不同的是,如果你希望将它划分为不同部分进行操作,你也可以方便的划分它。对于一个splitstring类,运行函数split()的结果是一个string类的vector(动态数组),这更像是其他的,高度封装的高级语言(例如python)的string类的split()。


为了这种方法可以更加方便地在大型工程中运用,class封装并放置在一个单独的库文件是很有必要的,并且你的代码应该包含它,注意在使用时应该将MAIN注释掉:

#define MAIN 1

#include <string>
#include <vector>
#include <iostream>
using namespace std;


class splitstring : public string {
    vector<string> flds;
public:
    splitstring(char *s) : string(s) { };
    vector<string>& split(char delim, int rep=0);
};

// split:需要一个分隔符,返回一个string类的vector 
// 正常情况下默认忽略重复的分隔符,除非rep参量值为1 
vector<string>& splitstring::split(char delim, int rep) {
    if (!flds.empty()) flds.clear();  //清空vector 
    string work = data();
    string buf = "";
    int i = 0;
    while (i < work.length()) {
        if (work[i] != delim)
            buf += work[i];
        else if (rep == 1) {
            flds.push_back(buf);
            buf = "";
        } else if (buf.length() > 0) {
            flds.push_back(buf);
            buf = "";
        }
        i++;
    }
    if (!buf.empty())
        flds.push_back(buf);
    return flds;
}

#ifdef MAIN
main()
{
    // 定义一个字符串 
    splitstring s("Humpty Dumpty sat on a wall.   Humpty Dumpty had a great fall");
    cout << s << endl;

    // 分离并输出分离结果 
    vector<string> flds = s.split(' ');
    for (int k = 0; k < flds.size(); k++)
        cout << k << " => " << flds[k] << endl;

    // 考虑重复的分隔符 
    cout << endl << "with repeated delimiters:" << endl;
    vector<string> flds2 = s.split(' ', 1);
    for (int k = 0; k < flds2.size(); k++)
        cout << k << " => " << flds2[k] << endl;

}
#endif

发布了58 篇原创文章 · 获赞 34 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_37666409/article/details/79770225